CUBE CONNECT Edition Help

Control Statements

The following control words are available in the Matrix program.

  • ABORT - Abort current program

  • ARRAY - Set arrays and values

  • BREAK - Break out of current process

  • BSEARCH - Finds a key or set of keys in a sorted array, or series of sorted arrays using a binary search.

  • CALL - Call user’s dll (external process)

  • CHOICE - Implement logit choice models (legacy command; Bentley recommends XCHOICE)

  • COMP - Compute variables from expressions

  • CONTINUE - Continue at end of loop statement

  • EXIT - Terminate current program

  • FILEI - Input files

  • FILEO - Output files

  • FILET - Set path for temporary files

  • FILLMW - Fill work matrices

  • FREQUENCY - Accumulate distributions of one matrix versus another

  • GOTO - Immediate jump to :label

  • IF … ELSEIF … ELSE … ENDIF - Define IF ENDIF block

  • JLOOP … ENDJLOOP - Define a loop for destination zones (J)

  • LOOKUP - Define lookup tables (see General Syntax)

  • LOOP … ENDLOOP - Define user controlled loop

  • PARAMETERS - Set static parameters

  • PRINT - Print variable values

  • PRINTROW - Print a row of a matrix (see General Syntax)

  • RENUMBER - Set zone renumber specifications

  • REPORT - Select standard reports

  • SET - Set multiple variables/arrays to same value

  • SORT - Sort user arrays

  • WRITE - Writes records to a DBF file defined by RECO

  • XCHOICE - Implement logit choice models

ABORT

Programs: Distribution, Fratar, Generation, Matrix

Aborts the entire run. Keywords include:

Use ABORT to terminate the program and return a fatal code to CUBE Voyager. Though not normally used, you can use this statement to terminate processing due to some detectable conditions. For example, suppose that during a mode-split process, the program detects walk access and drive access between the same zone pair, but you know that this should not occur. You can create a test to find this and abort if it occurs.

  • MSG - |S| - Optional message that can be printed when the program terminates. For readability, Bentley recommends 100 characters or less.

Example

IF (MW[1][I] != 0) ABORT  ; Intrazonal present in MW[1]
INTRA = MW[1][I]
IF (! INTRA)
  LIST='No intrazonal value for MW[1] at Zone ', I
  ABORT
ENDIF

ARRAY

Programs: Distribution, Fratar, Generation, Matrix

Declares user single and multi-dimension arrays. Keywords include:

Beginning in version 5.1, multi-dimension arrays can be specified. This has caused the standard ARRAY statement to take on a new format. The previous format for specifying string arrays (StringArray=arraysize-stringsize) is no longer valid and must be modified to the new format. The keyword TYPE is used to specify the size and mode of the array elements for the arrays that follow it. Multi-dimension arrays provide considerably more capability – the user can specify up to 9 dimensions for a single array. However, multi-dimension arrays can take up a significant amount of memory so their usage must be carefully planned. For example, a double precision array of 1000x1000x100 will take up 800 MB of memory.

Use ARRAY to allocate user arrays. An array is different from a variable in that it represents vectored data. Values stored to arrays in this program can be numeric or string. When an array is referenced in an expression, it must include all the indices [ ], and if any index exceeds its corresponding size, the program will fatally terminate. Arrays can be useful for different processes; a common use may be to store information for specific zones. ARRAY statements are not dynamic (stack oriented); they are allocated prior to any stack operations. When a single dimensioned array appears in a SET statement, all the cells in the array are set to the same value. Multi-dimensioned arrays can also be specified with the AUTOMDARRAY keyword on the FILEI MATI|DBI statements, but the use of those arrays is somewhat different.

  • ARRAYNAME - |I,…| - Name of the array that is to be allocated according to the specified size: n. ARRAYNAME must be a unique name. The values following the keyword represent the highest indexes possible for the array. The values must be either a numeric constant, or ZONES. Arrays are cleared when they are allocated. The preceding TYPE= keyword sets the size of the individual cells of the array, and the mode (numeric or string) for the cells.

  • TYPE - |S| - Specifies the size of each array cell. If the array is to be numeric, the value may be the number 1, 2 or 4 to indicate 1-byte (range -128 to +127), 2-byte (range - 32768 to +32767) or 4-byte (range -2147483648 to +2147483647) integer data, or the letter F or D, to indicate single (+- 1.5 x 10^-45 to 3.4 x 10^38 with 7-8 significant digits) or double precision (+- 5.0 x 10^-324 to 1.7 x 10^308 with 15-16 significant digits) real data. If the array is to contain string data, the value should be preceded by the letter C followed by the maximum string size; however, any numeric value other than 1, 2 or 4 will automatically be cast as string. Strings are limited to 999 characters.

    The default TYPE is D (double). The user must choose the correct data type for the array that are big enough to hold the anticipated data but minimize memory usage. Storing bigger values in smaller size arrays will not cause errors or warnings. The values are simply truncated or modulated to fit the array element size.

Additional system variables are available so the properties of an array can be accessed in the script:

  • arrayname.type — a string that is the same as in the TYPE keyword

  • arrayname.dimension — the number of dimensions

  • arrayname.size[] — an array of integers for the size of each dimension

When multi-dimension arrays are referenced in COMP statements, several deviations from the standard COMP syntax rules are available to the user. For example:

COMP MDARRAY=value; no indices supplied indicate that the entire array (all cells) is to be populated with value.

COMP MDARRAY1=MDARRAY2; no indices for both arraynames, and the right side value is only a multi-dimension array that has the same dimensions and mode as the left side multi-dimension array.

Such a statement will cause all the elements from MDARRAY2 to be copied to MDARRAY1. If the element sizes of the arrays are different, the elements will be converted during the copy.

COMP MDARRAY[#n][#n]… = expression will cause an automatic internal loop for the indexes that have #n specified. The loop will begin at 1 and continue until to the number of cells declared for that index is reached. However, if the same #n is specified for more than one index, the smallest dimension will be used as the upper limit. The n in #n may be 1 - the number of indexes for the array. (array[#3][2][#3] would be valid for a 3 dimensioned array.) If the expression does not contain any reference to any of the #n’s in the result array, the statement is executed in a very efficient manner – it can be literally thousands of times faster than through the use of LOOP/ENDLOOP controls for the statement. The #n can be #1 up to #9, these variables are actually place holders, so the first subscript could actually be [#9]. Any #n subscript for the result can be used as a subscript or as a variable in the expression. But, a #n in the expression that does not appear as a subscript in the result will cause a fatal error.

By default, any #n index in the result will cause an internal loop from 1 to the upper limit of that index. However, the user can cause a filter to be invoked within the loop. This is done by using #n keywords with ranges following the expression. Eg; ARRAY array1=15,50; COMP array1[#1][#2] = expression, #1=1,3,8-10, #2=20-max…. In this COMP statement (without the added sub keywords), #1 would normally loop from 1 to 15 and #2 would loop from 1-50. But, with the added keywords, #1 would loop from 1-10, and would be applied only for values of 1, 3, and 8-10, and #2 would loop from 20 to 50. The values for #n sub-keys can be integers, simple variable names, or the word MAX, which may be used to specify the upper limit for that dimension. If a pair of values is specified, a test will be done to see if the loop values for #n fall between the limits of the pair – the first value need not be the lower value, but it is recommended to code any pair as low-high. Filter values outside of the valid range for the dimension will not cause an error, they will simply be ignored.

Although all the above computations could be completed with standard scripts using loops, the short-cut methods shown above can reduce user coded script, and can drastically improve execution times.

Example

ARRAY sum_mat=10, cbd2ext=500
IF (M <= 10) sum_mat[M] = sum_mat[M] + rowsum(M)
IF (I=1-10,51-58,63,96) cbd2ext[I] = cbd2ext[i] + MW[1] include=501-535
ARRAY row_total=zones

; example of defining a string array
ARRAY TYPE=C5 StrArray=1000; defines a string array with size of 1000 and a character width of 5.
ARRAY array1=zones,50; Array1 is a double precision (8 byte) array dimensioned [zones][50]
COMP array1[#1][#2] = expression, #1=1,3,8-10, #2=20-max....

BREAK

Programs: Distribution, Fratar, Generation, Matrix

Use BREAK to break out of a loop. When encountered, control immediately passes to the stack statement after the associated end of loop. If BREAK is within a LOOP or JLOOP block, control passes to the statement following the associated ENDLOOP (loop variable remains intact) or ENDJLOOP (J will be reset to 1). Otherwise, stack processing for the I zone is terminated but output and zonal reporting statistics will not be bypassed.

Example

LOOP  L1=1,3
  IF (condition)
    statements
  ELSE
    BREAK ; jump to IF statement
  ENDIF
ENDLOOP
IF (condition) BREAK ; no more processing for this origin zone
LOOP L2=K1,K2,KINC
  JLOOP EXCLUDE=25-50,88
    IF (condition) BREAK ; jump to LOOP L3=
  ENDJLOOP
  LOOP L3=L2,L2+5
    IF (condition) BREAK; ; jump to ABC=
  ENDLOOP
  ABC=...
ENDLOOP

BSEARCH

Program: Matrix

Performs a binary search to find a key or set of keys in a sorted array or series of sorted arrays. The format is:

BSEARCHARRAY=value,ARRAY=value,...

ARRAY |N| is the name of a user array that is in ascending sort. The routine will do a binary search to expedite the search for the key. If there are multiple arrays specified, the search will begin at the first array and then proceed through the remaining arrays for matching keys (at the same record level as the first array). All arrays must be in ascending sort.

If the array is a string (C) array, any constant value must be placed within quotes. If the value is an expression, the result of the expression must be a string.

BSEARCH stores results in the variable _BSEARCH. Possible values in _BSEARCH are:

  • +n — Indicates an exact match was found at the nth location in the array

  • -n — Indicates that no match was found, but the nth location is where one would insert the key (that is, the nth location is higher than the key, and the n-1 location is lower than the key).

  • 0 — Indicates that the key is greater than the value in the highest location in the array.

Example

ARRAY     MYARRAY=100, YOURARRAY=100
some code to populate the arrays

SORT    ARRAY=MYARRAY,YOURARRAY
BSEARCH  MYARRAY=32, YOURARRAY=(MYARRAY[j]*3)

Example

FILEI DBI[1]=MYDBF, AUTOARRAY=FIELD1 SORT=FIELD1
ARRAY MYARRAY=100, YOURARRAY=100

BSEARCH DBA.1.FIELD1='875'

CALL

Programs: Distribution, Fratar, Generation, Matrix

Executes an external routine. Keywords include:

Use CALL to execute an external process. To use this statement, there must be an external file that is a dynamic link library (DLL), which contains the entry point that is desired to be used at this location. The DLL file may have multiple entry points, and they can all be accessed by this run of the Matrix program.

  • DLL - |S| - Single string that contains the DLL file name, without extension, followed by the name of the routine entry point enclosed within parentheses. The "DLL" extension is appended by the program. In some operating systems, the file name may be case sensitive. The routine name is usually case sensitive; this depends upon the compiler/linker system used to develop the DLL.

    Note: The compiler/linker system that was used to develop the DLL might have added some characters to the entry name: Borland C/C++ compilers prefix the entry name with an underscore.

The routine is called with one argument: the address of a structure that contains: I, J, Zones, Iteration, address of MW, address of a routine to obtain address of any variables, and address of a routine to print messages. The calling process adheres to standard "C" notation. The C structure is illustrated in the sample code section below. I, J, Zones, and Iteration are passed as integers. The addresses of these variables could be found by using the pfFindVar routine, but because these variables must be protected, pfFindVar will return NULL if the routine tries to obtain their addresses.

MW is the address of an array of pointers to the individual MW arrays. MW[1] is the address of the first cell for MW[1]. Note that this is the cell for column 0, NOT column 1. MW[1][1] would be the correct notation to address the cell for zone 1 in MW[1]. MWs are allocated individually, rather than as a single block. In Fortran (without pointers), the access to MW[1][1] would NOT be the typical MW(1,1). Instead, the address of each MW would have to be obtained individually, and passed through an interface to a separate routine for actual use of the MW. The routine would probably declare the array as: DOUBLE PRECISION MW1(0:*).

The MW array can be accessed in several ways:

  • Saving the MW value from the passed structure — the suggested way if MWs need not be allocated, and there are many references to MWs.

  • Saving the address returned from pfVarFind (“MW”…) — the required way if MWs need to be allocated.

  • Indirect referencing to MW from the passed structure — an efficient way if MWs need not be allocated, and there are not many references to MWs. Indirect referencing is not quite as efficient as direct addressing, but there is minimal difference.

The pfFindVar routine is used to obtain the pointer to any variables that are to be made available to the external process. All variables (with a few isolated exceptions) are stored as double precision values. Calls to pfFindVar need to be made only during the first entry into the procedure; the returned addresses can be stored in static cells so that pfFfindVar need not be called on every entry. The Matrix program allocates MW arrays only when it is necessary, so the routine has to make sure that any MWs that it wishes to use are allocated. This can be done by calling pFfindVar for MW, and appending the integer numbers of the MWs that the procedure will use. If this is not done, and the routine accesses an MW that has not been allocated, the routine will access a dummy array. If the user is sure that all the desired MWs have been previously allocated by the Matrix program, pfFindVar need not be used at all.

The pfPrnLine function is called, with two arguments, to print a message:

  • nCtl — The control word for print the message. It has the format SFEN where,

    • F is a 1 if the message is to be written to the error file

    • E is the level of the message (0,1,2=Message, Warning, Fatal),

    • N is the number of new lines to print before printing the message.

  • sMmessage — The message string (ASCIIZ) to be printed; it may contain any normal printer characters, including n, r,f,t etc.

Example

CALL DLL=user(_User1) ; call the following code in user.dll
// Sample of user function code in C
/*TITLE: User1 -- user function*/
#include <stdio.h>
typedef struct { int        I, J, Zones, Iteration;
                 double**   MW;
                 void* (*pfFindVar)(char*,...);
                 void*      (*pfPrnLine)(int, char*);
                } CallStack;
int _export User1 (CallStack* Stack)
{
    char    message[100];
    static  double** MW=NULL;   /* store the address of MW array */
    int     m,j;
/*
 *  At first entry (when MW==NULL),
 *  establish MW and insure that MW[1-5] have been allocated
 */
  if (MW == NULL) {
      MW = (*Stack->pfFindVar)("MW",1,2,3,4,5);
      /* Example of forming a message */
      sprintf(message,"User1 Call I=%i, J=%i, Zones=%i",
          Stack->I, Stack->J, Stack->Zones);
      /* Example of printing a message */
      (*Stack->pfPrnLine)(1,message);
  }
/* Sample to fill in MW[1-5] */
  for (m=1; m<=5; m++)
    for (j=1; j<=Stack->Zones; j++)
      MW[m][j] = Stack->I*100 + m*10 + j;
  /* Stack->MW[m][j] is a similar way to reference MW[m][j] */
  return 0;
}

CHOICE

Program: Matrix

Implements a logit-choice model.

Note: XCHOICE is the preferred command statement for implementing logit-choice models.

Use the CHOICE command to implement logit-choice models, which can be based either on generalized costs or utilities. The actual keywords supported depend on whether you use cost-based or utility-based models:

CHOICE keywords: Cost-based models

Keywords and sub-keywords applicable to CHOICE cost-based models include:

CHOICE Keywords: Cost-based models

  • ALTERNATIVES - |S99| - Lists the set of discrete choices in the forecast scenario. If the model is confined to destination choice, then the alternatives list comprises just one item (representing the demand matrix). The names used in the alternatives list are subsequently used in SPLIT or DESTSPLIT commands which define the structure of the logit choice model, and also determine the order that input or output data are specified.

  • BASECOSTS - |S99| - Supplies the names of the base-cost variables. For lists of two or more variables, the order must match the list of choices given in the ALTERNATIVES clause.

    This clause is only used in incremental models which specify base and forecast costs (as opposed to cost differences). The corresponding forecast costs are specified using the COSTS clause.

  • BASEDEMAND - |S99| - Supplies the names of the base-demand variables for incremental models only. For lists of two or more variables, the order must match that in the ALTERNATIVES clause.

  • COSTS - |S99| - Specifies forecast costs. If there is more than one cost specified, their order must be the same as that used in the ALTERNATIVES clause.

    See also BASECOSTS and DCOSTS (cost-differences) for incremental models; the COSTS clause is not used in conjunction with the latter.

  • DCOSTS - |S99| - For incremental models only, the change in cost for each choice can be given instead of the base and forecast costs. These cost-differences may be specified as matrices, or numeric values such as 0.0.

  • DEMAND - |S| - Specifies total demand for an absolute model. Demand is typically a matrix, although numeric values may be specified. For example, a demand of 100.0 will give output demand corresponding to the percentages which choose each alternative.

  • DESTSPLIT - |S99| - The DESTSPLIT clause is used when the nest in the hierarchy corresponds to a destination choice model. It divides the travel demand between destination zones, rather than alternatives. The output list must comprise just one item, representing either a distinct choice from the ALTERNATIVES clause or an output which links to a subnest.

    Like the SPLIT command, it may be specified in one clause or divided into constituent parts by use of the COEFF and SPLITINTO clauses. Examples are:

    DESTSPLIT = TOTAL, 0.3, allTrips,

    and

    DESTSPLIT = TOTAL, COEFF = 0.3, SPLITINTO = allTrips,

    By default the destination choice model works over all zones. By using the INCLUDE or EXCLUDE clauses the choice process may be restricted to a subset of all zones. The following example shows destination choice over zones 1 to 57:

    DESTSPLIT = TOTAL, 0.3, allTrips, INCLUDE=1-57,

    This shows destination choice over zones except for 88 to 100, which are specified by the EXCLUDE subkeyword:

    DESTSPLIT = TOTAL, COEFF=0.3, SPLITINTO=allTrips, EXCLUDE=88-100,

    Note that certain restrictions apply to the use of destination choice models. The composite costs may not be saved, and this form of logit model may not be used inside a JLOOP construct.

    • COEFF - |S|

    • INCLUDE - |IPa|

    • EXCLUDE - |IPa|

    • SPLITINTO - |S99|

  • OCOMPCOST - |I| - Optional. Outputs the composite cost of all choices for an absolute model. The list contains a numeric value, which specifies the working matrix (MW) that stores the result. Where the choice model has a hierarchic structure, the composite cost for the highest level nest may be saved. This clause is not supported for destination-choice models, as the composite costs are zonal values rather than matrices.

  • ODEMAND - |I| - Specifies the working matrices (MWs) used to store the forecast demand; the list comprises a list of working matrix numbers. If there is more than one cost variable, then the list must be in the same order as used in the ALTERNATIVES clause.

    This command is optional, and may be omitted if only the composite costs are required.

  • SPLIT - |S99| - The structure of the logit choice model is specified by the SPLIT and DESTSPLIT clauses. One of these clauses is required for each nest (or subnest) in the model hierarchy. For a hierarchic model, these are typically specified starting at the top-level and working down the structure.

    Each SPLIT clause specifies an input, a scale parameter (or coefficient of cost), and one or more outputs. The coefficient and outputs may both be specified in the SPLIT clause or specified using the COEFF and SPLITINTO subkeyword clauses.

    The input (or first item listed in a SPLIT clause) may either be TOTAL (representing the total demand at the top level of the choice hierarchy) or for subnests it is the name of an output from the appropriate higher level nest.

    The coefficient is specified as the second item in the SPLIT clause, or using the COEFF subclause. It may be specified as a numeric value, a variable, or even a matrix with differing values between origin-destination pairs. The latter is appropriate when the demand matrix comprises distinct segments (such as travel within study area, trips from cordon into study area, and through traffic) and these segments respond differently to cost differences.

    The remainder of the SPLIT clause, or the SPLITINTO clause define the output list. The items represent either distinct choices (from the ALTERNATIVES clause), or links to subnests which are given unique meaningful names and used as inputs to lower splits.

    The following examples shows a subnest taking AllPT as an input and using a scale parameter of 0.3 to divide between bus and rail alternatives. Specified as a SPLIT clause it takes the form:

    SPLIT = AllPT, 0.3, Bus, Rail,

    and using subkeywords it is:

    SPLIT=AllPT, COEFF=0.3, SPLITINTO=Bus, Rail,
    • COEFF |S|

    • SPLITINTO - |99|

  • STARTMW - |I| - The calculations performed by the logit choice model require a number of working matrices (or MWs) to be allocated for the use of the CHOICE command. The STARTMW clause specifies a numeric value corresponding to a particular working matrix which is higher than that of any other working matrix referenced in the script. Working matrices from the STARTMW value upwards are used by the CHOICE command, and should not be used elsewhere in the script. Where a Matrix script contains several CHOICE commands, the same STARTMW value may be used in all instances.

CHOICE keywords: Utility-based models

Keywords and sub-keywords applicable to CHOICE utility-based models include:

CHOICE Keywords: Utility-based models

  • ALTERNATIVES - |S99| - Lists the set of discrete choices in the forecast scenario. If the model is confined to destination choice, then the alternatives list comprises just one item (representing the demand matrix). The names used in the alternatives list are subsequently used in SPLIT or DESTSPLIT commands which define the structure of the logit-choice model, and also determine the order that input or output data are specified.

  • BASEDEMAND - |S99| - Supplies the names of the base-demand variables. For incremental models only. For lists of two or more variables, the order must match that in the ALTERNATIVES clause.

  • BASEUTILS - |S99| - Supplies the names of the base utilities for the various alternatives. For lists of two or more variables, the order must match that given in the ALTERNATIVES clause.

    This clause is only used in incremental models which specify base and forecast utilities (as opposed to utility differences). The corresponding forecast costs are specified using the UTILITIES clause.

  • DEMAND - |S| - Specifies the total demand for an absolute model. Demand is typically a matrix, although numeric values may be specified. For example, a demand of 100.0 will give output demand corresponding to the percentages which choose each alternative.

  • DESTSPLIT - |S99| - Use the DESTSPLIT clause when the nest in the hierarchy corresponds to a destination-choice model. It divides the travel demand between destination zones, rather than alternatives. The output list must comprise just one item, representing either a distinct choice from the ALTERNATIVES clause or an output which links to a subnest. This output item may be preceded by a scale parameter.

    The following example applies a scaling factor to the ModeSplit logsum utility, and performs a destination choice dividing the total trips across all destinations:

    DESTSPLIT = TOTAL 0.9 ModeSplit,

    By default the destination-choice model works over all zones. By using the INCLUDE or EXCLUDE subkeyword clauses the choice process may be restricted to a sub-set of all zones. The following example restricts destination choice to zones 1 to 23:

    SPLIT=TOTAL,allTrips,INCLUDE=1-23,

    Note: Certain restrictions apply to the use of destination- choice models. The composite utilities cannot be saved, and this form of logit model may not be used inside a JLOOP.

    • INCLUDE - |IPa|

    • EXCLUDE - |IPa|

  • DUTILS - |S99| - Gives the change in utility for each choice rather than the base and forecast utilities. For incremental models only. These utility-differences may be specified as matrices, or numeric values such as 0.0.

  • OCOMPUTIL - |I| - Optional. Outputs the composite utility (or logsum value) of all choices for an absolute model. The list contains a numeric value which specifies which working matrix (MW) is used to store the result. Where the choice model has a hierarchic structure, the composite utility for the highest level nest may be saved. This clause is not supported for destination-choice models, as the composite costs are zonal values rather than matrices.

  • ODEMAND - |I| - Optional. Specifies the working matrices (MWs) used to store the forecast demand; the list comprises a list of working matrix numbers. If there is more than one cost variable, then the list must be in the same order as used in the ALTERNATIVES clause.

    This command may be omitted if only the composite costs are required.

  • SPLIT - |S99| - The structure of the logit choice model is specified by the SPLIT and DESTSPLIT clauses. One of these clauses is required for each nest (or subnest) in the model hierarchy. For a hierarchic model, these are typically specified starting at the top-level and working down the structure.

    Each SPLIT clause specifies an input, and one or more outputs which may have their own scale parameters. (A choice with only one output may be specified to apply a scaling factor to a sub-nest logsum utility, and so achieve consistent scaling at all equivalent levels in a complex hierarchic structure.)

    The input (or first item listed in a SPLIT clause) may either be TOTAL (representing the total demand at the top level of the choice hierarchy) or for subnests it is the name of an output from the appropriate higher level nest.

    The remainder of the SPLIT clause define the output list, and any scale parameters which apply to subnests.

    The main items in the output list represent either distinct choices (from the ALTERNATIVES clause), or links to sub- nests which are given unique meaningful names and used as inputs to lower splits. An example is:

    SPLIT=AllPT Bus Rail,

    Subnests in the output list may be preceded by a scale parameter, which is applied to the composite (or logsum) utility of the subnest before evaluating this choice nest. The scale parameter should be greater than 0, and must not exceed 1.0. The scale parameter may be omitted where its value is 1.0, as this is the assumed default. Examples are:

    SPLIT=TOTAL Car 0.5 PT 0.4 WalkCycle,

    where scale parameters are applied to the PT and walk/cycle subnests. Car either is a distinct alternative, or a subnest with a default scale parameter of 1.0.

    Where the same scale parameter applies to several subnests, the scale parameter may be specified once followed by the list of relevant subnests grouped together by use of brackets. An example is:

    SPLIT = TOTAL, 0.4 Car 0.5 (Bus Rail),

    where the bus and rail subnests share the same scale parameter, and a different value applies to the car subnest.

  • STARTMW - |I| - The calculations performed by the logit choice model require a number of working matrices (or MWs) to be allocated for the use of the CHOICE command. The STARTMW clause specifies a numeric value corresponding to a particular working matrix which is higher than that of any other working matrix referenced in the script. Working matrices from the STARTMW value upwards are used by the CHOICE command, and should not be used elsewhere in the script. Where a Matrix script contains several CHOICE commands, the same STARTMW value may be used in all instances.

  • UTILITIES - |S99| - Specifies forecast utilities. If there is more than one utility, their order must be the same as that used in the ALTERNATIVES clause.

    See also BASEUTILS and DUTILS (utility-differences) for incremental models; the UTILITIES clause is not used in conjunction with DUTILS.

COMP

Programs: Distribution, Fratar, Generation, Matrix

Computes a variable, matrix, or matrix element. Keywords and sub- keywords include:

Usage is:

VAR=expression
MW[]=expression(INCLUDE EXCLUDE)

The COMP statement is probably the most important of all the statements in the program. It is used to compute variable and work matrix values.

COMP Keywords

  • MW - |KN| - Working matrix that you can use to store values between origin zones and destination zones (I zones and J zones). Set the keyword equal to an expression you want to solve and store in a working matrix. You can specify working matrix expressions per origin zone or per origin zone and destination zone:

    • MW[n] — For the current origin zone (I), defines the expression solved for all destination zones (all values of J). The Matrix program’s internal I-loop specifies I. The Matrix program stores the values in working matrix n. You may define up to MAXMW working matrices. You may specify the index n using a constant or a variable name.

      The program solves the expression for all values of J (1 through ZONES), filtering values indicated by any INCLUDE or EXCLUDE lists on this statement.

      Within a JLOOP statement, the program only solves the expression one time only, with J being the value of the loop’s current J.

    • MW[n][d] — For the current origin zone (I), defines the expression to solve at destination zone d. The second index, d, must be between one and ZONES. The Matrix program stores the computed value in working matrix n.

    • EXCLUDE - |IP| - Optional. Values of J excluded when computing the MW[n] expression. As the program internally loops on J, the program compares J to the values in the EXCLUDE list. If the current J is on the list, the program does not evaluate or store the expression for that J.

      Specified values can range from 1 to the highest zone number.

      Filter applies to all MW[n] values on the COMP statement.

      Not permitted if COMP statement within JLOOP … ENDJLOOP block.

      Always processed after INCLUDE subkeyword.

      By default no zones are excluded.

    • INCLUDE - |IPN| - Optional. Values of J included when computing the MW[n] expression. As the program internally loops on J, the program compares J to the values in the INCLUDE list. If the current J is not on the list, the program does not evaluate or store the expression for that J.

    Specified values can range from 1 to the highest zone number. Filter applies to all MW[n] values on the COMP statement.

    Not permitted if COMP statement within JLOOP … ENDJLOOP block.

    By default all zones are included.

  • VAR - |KN| - VAR is the name of a variable where the result of expression is to be stored. The name may be as long as desired (within reason). The expression is solved one time for each encounter, with J being either one (not in JLOOP), or the value of the JLOOP J. If expression results in a character string, the variable must be a character string variable. All variables are assumed to be numeric variables, unless their first appearance as a result in a COMP statement is with an expression that results in a character string. Examples:

    abc = '123'
    def = 123
    abc = def ; invalid: abc has been declared a string
    abc = abc+'456' ; valid
    abc = abc+def ; messy -- don’t mix types
    jkl = 1 ; jkl is declared numeric
    jkl = xyz ; invalid: xyz is declared a string (later)
    xyz = 'xyz' ; xyz is declared a string

    The program does not always bother computing expressions for variables that are not used as input to some process. In the above examples, the statements with jkl= might never be executed, because jkl is never used.

If a COMP statement includes any INCLUDE or EXCLUDE filters, the filters apply to all MW[]= values, and special matrix functions on the statement, no matter where they appear on the statement. EXCLUDE is processed after INCLUDE. INCLUDE and EXCLUDE may not be specified within a JLOOP block.

Supported expressions

Special Matrix variables:

MW[] MI.n.name, MI.n.matnum, MI.n.name.T, MI.n.matnum.T

The expression is a standard CUBE Voyager numeric expression, but there are also certain special variables names that may be used within it.

  • MW[Rexpression] - Value from any work matrix; the column index (not explicitly expressed) will be supplied as J. Rexpression may contain nested MW[]; be careful! MW[Rexpression][Cexpression] is the value from any work matrix for zone Cexpression.

  • MI.n.name - Value from the MATI[n].name matrix; the column index (not explicitly expressed) will be supplied as J. The row index [n], must be a constant. MI.n.name[Cexpression] is a variation; the column index is computed.

  • Valid matrix names contain only alphanumeric characters, spaces, and underscores (_). If matrix names have spaces, then you must include the entire MI matrix reference in double quotes to recognize the name. For example:

    MW[1]="MI.1HBW TRIPS"
    		  
  • MI.n.matnum - Value from the MI[n].matnum matrix; the column index (not explicitly expressed) will be supplied as J. The row index [n] and the matnum must be constants. MI.n.matnum[Cexpression] is a variation; the column index is computed.

  • MI.n.name.T, MI.n.matnum.T - Special cases for the above two MI formats. The appended “.T” indicates to use the transposed values for the matrix. This triggers a preprocessor program that will transpose the matrix. Thus, the retrieved cell represents the J-I value, instead of the I-J value. If a column index is used, the retrieved cell will represent the value of the cell for the index to I.

  • ZI.n.name - Value from the ZDATI[n].name matrix; the zone index (not explicitly expressed) will be supplied as I. ZI.n.name[Cexpression] is a variation; the zone index is computed.

The expression may contain the following special matrix row processing functions:

ROWSUM() ROWCNT() ROWMIN() ROWMAX() ROWAVE() ROWFIX() ROWFAC() LOWEST() ROWADD() ROWMPY() ROWDIV() ROWREAD()

In addition to the standard numeric expression functions (abs, exp, int, ln, log, max, min, round, sqrt—see Expressions for more details), some special purpose functions are available. The matrix oriented functions process all cells in a matrix (subject to the restrictions of any INCLUDE and EXCLUDE lists), and should not be used within JLOOP blocks and MW[]= expressions.

Most of these functions could be duplicated with a combination of MW[]= statements. The function format has two advantages: coding is much easier, and processing is more efficient. Combining functions on a single statement is permissible; they will be processed in appropriate order. Example: DUMMY=ROWFAC(3,1.5)+ROWFIX(3) will factor matrix 3 and then integerize it.

In the following matrix function descriptions, the first argument (mw) indicates the work matrix to process, and must be specified. If "lo,hi" is allowed, and lo is supplied, and hi is not, hi will be set to lo. Lo and hi are inclusive values. If an invalid argument is detected by a function, the function will return a zero, without any diagnostics.

MATRIX function descriptions

  • ARRAYSUM(array_name) - Returns sum of an array (see Examples and FAQ).

  • LOWCNT - Stores actual number of cells used in LOWEST. Warning: Dividing by LOWCNT, if it is 0, will cause a program error message. In some cases, you can use the max function to prevent this. For example:

    W[mw][I]=LOWEST(mw,4,.01,5,I)
    /max(1,LOWCNT)/2
  • LOWEST (mw,#) - Sum of lowest # cells

  • LOWEST(mw,#,lo,hi) - Sum of lowest # cells where lo>=value<=hi

  • LOWEST(mw,#,lo,hi,z,z,…) - Sum of lowest # cells but exclude specific cells

    LOWEST is quite useful for computing an intrazonal value based upon the proximity to the nearest zones. The range of arguments accommodates most situations. Use lo and hi to exclude possible dummy zones that appear as zero in the row. Use z to exclude specific zones; normally, the intrazonal cell (I) would be excluded. This exclusion is in addition to any on an EXCLUDE list.

    Note: LOWEST treats zeros as regular numbers. Since all MWs are initialized to zeros, use caution when applying LOWEST with no range specified.

  • MATVAL (F, M, I, J [, E]) - Returns random access values from MATIs (see see Examples and FAQ).

    F = MATI[#] M=Matrix# I=I J=J E = the value to return if the request for the cell is invalid.

    Each of the arguments can be an expression, variable, or constant. Because the arguments are dynamically set, the program can not pre-edit the values. For example:

    K = matval(3,1,I,J,-1) indicates to get the value from I to J from matrix 1 on MATI[3].

    Since this is direct access, the function can be slow in some cases and quite efficient in others. The Matrix program maintains a cache of the matrix rows to try to help speed up the process. However, some types of processing will not be helped much by the use of the cache. In general the larger the cache, the more efficient the access will be. The cache size is specified by the PARAMETERS MATVALCACHE.

  • ROWADD(d,s1…sn) - Add matrix mw[1] + … mw[sn] into mw[d]

    Same as:

    MW[d]= MW[s1] + MW[s2] + MW[sn]
  • ROWAVE(mw) - Average cell value for nonzero values

  • ROWAVE(mw,lo,hi) - Average cell value for nonzero values, including only cells where: lo>=value<=hi

  • ROWCNT(mw) - Number of cells with nonzero values

  • ROWCNT(mw,lo,hi) - Number of cells with nonzero values, but include only cells where: lo>=value<=hi (this can include 0).

  • ROWDIV(d,s) - Divide MW[d] by MW[s] making all divided-by- zero cells equal to 0.

    Same as:

    JLOOP
       IF (MW[s] == 0)
         MW[d] = 0
       ELSE
         MW[d] = MW[d] / MW[s]
       ENDIF
    ENDJLOOP
  • ROWFAC (mw,fac) - Factors the row by fac.

    Same as:

    MW[mw] = MW[mw] * fac
  • ROWFIX(mw) - Integerize mw (start at column intrazonal + 1, with rounding factor = 0);

  • ROWFIX(mw,n) - Integerize mw (start at column n, w/ rounding factor = 0)

  • ROWFIX(mw,n,rnd) - Integerize mw (start at column n, using specified rounding factor, rnd)

    ROWFIX integerizes the values in each cell of the matrix (that is, drops all fractional portions of the number). ROWFIX ensures the integer total is consistent with the original total. It integerizes each cell after adding the rounding factor and the accumulated fractional portions from the previously treated cells. With a rounding factor of 0, each cell is truncated and its fractional remainder is carried to the next cell. With a rounding factor of 0.5, each cell is rounded to the nearest integer and the difference (original – rounded) is carried to the next cell.

    If the process always begins at zone 1, the lowest numbered zones never gets their fair share of the fractions. To eliminate this bias, the default condition starts at the cell after the intrazonal cell and wraps around until the intrazonal cell is the last cell processed. The optional second argument specifies which cell the process is to end with.

  • ROWMAX(mw) - Maximum value in the row

  • ROWMIN(mw) - Minimum value in the row

  • ROWMPY(d,s) - Multiply MW[d] by MW[s]

  • ROWREAD(MW#, MATI#, I, M) - Same as:

    MW[d] = MW[d] * MW[s]
  • ROWREAD(MW#, MATI#, I, M) - Reads a random row from the input matrix and places it in the current row of the referenced working matrix. Allows for processing input matrix data not in I zone ascending sort order.

    Where:

    MW# — Desired MW to which the record will be saved

    MATI# — Number of the input matrix file being accessed (Mati[#])

    I — Desired origin zone

    M — Desired matrix number on the input file to process

    Example

    run pgm=matrix
    FILEI MATI[1]=trips00.mat
      ; input matrix
      ; with random I zone order from
      ; external user program
    FILEO
    MATO[1]=Fixed_trips00.mat,mo=1-20, dec=20*8
    ; Matrix automatically runs an ILOOP
    ; from I=1 to I=ZONES
    loop m=1,20
      ; loop over the 20 matrices
      ; in the input file
    x=ROWREAD(m,1,I,m)
      ; read row for the
      ; current value of I and places it ; in the work matrix
    endloop
    endrun
  • ROWSUM(mw) - Row total

  • ROWSUM(mw,lo,hi) - Row total, but include only cells where: lo>=value<=hi

Note: mw is a working matrix number (that is, MW[1])

lo is the lo end of a range

hi is the hi end of a range; defaults to lo if not specified

Example

MW[2]=J
MW[K]=MW[2] * MW[5] / SQRT(A*MW[3][MW[22]])
A=1, B=2, MW[A]=A+B INCLUDE=1-5,8,47-93
MW[3]=5*A, MW[4]=MW[3]*2, MW[K][I%10+1]=ODD,
INCLUDE=1-100,401-500, EXCLUDE=90,93,452; will apply to all MW[]s=
ABC=LOOKUP(DEF)*3
; move input matrices to work areas
MW[11]=MI.1.1, MW[12]=MI.1.2, MW[13]=MI.1.3
MW[21]=MI.2.1, MW[22]=MI.2.2, MW[23]=MI.1.3
JLOOP J=I
MW[6]=J ; store only at intrazonal column
ENDJLOOP
set var=sumaf1,rowsum1 ; clear variables
lookup name=f1, file=f1.txt
JLOOP
rowsum1 = rowsum1 + mw[1] ; get total for mw[1]
mw[2] = zi.1.attr[j] * f1(mi.12.1) ; A * F's
sumaf1 = sumaf1 + mw[2] ; sum A*F
endjloop
; Next line is same process done with functions:
rowsum1=ROWSUM(1) mw[2]=zi.1.attr[j]*f1(MI.12.1) sumaf1=ROWSUM(2)

CONTINUE

Programs: Distribution, Fratar, Generation, Matrix

Jumps to end of loop.

Use CONTINUE to immediately jump to the end of a loop, bypassing all stack statements between it and its associated end of loop. If it is within a LOOP or JLOOP block, control passes to the appropriate ENDLOOP or ENDJLOOP statement. Otherwise, stack processing for the I zone is terminated but output and zonal reporting statistics will not be bypassed.

Example

LOOP  L1=1,3
  IF (!(condition)) CONTINUE
ENDLOOP
IF (condition) CONTINUE ; no more processing for this origin zone
LOOP  L2=K1,K2,KINC
  JLOOP EXCLUDE=25-50,88
  IF (condition) CONTINUE ; jump to ENDJLOOP
  .
  ENDJLOOP
  LOOP L3=L2,L2+5
  IF (condition) CONTINUE ; jump to ENDLOOP for L3
  .
  ENDLOOP
ENDLOOP

EXIT

Programs: Distribution, Fratar, Generation, Matrix

Exit the program before the end of zone processing

Upon encountering EXIT, the program immediately terminates stack processing, and goes to the end of I-loop processing.

Example

IF(expression)EXIT

FILEI

Note: See FILEI for general information about FILEI and for important limitations when using Application Editor.

Programs: Distribution, Fratar, Generation, Matrix

Selects input data files. Keywords and sub-keywords include:

FILEI input data is normally entered in either matrix format or zonal vector format. Matrix data is read dynamically (at the start of each I- loop), and must be in origin zone (I) order, whereas zonal data is read prior to the initiation of the I-loop, and need not be in any specified order. Data from these files is accessed via COMP statements, and are identified as MI.n.name and ZI.n.name. The n designates subscript of the file, name designates the matrix name or number. CUBE Voyager matrices can have names and/or numbers, other matrices have only numbers, and zonal data files have names only. Example: MI.1.3 indicates matrix number 3 on the MATI[1] file. ZI.6.POP indicates the POP variable from ZDATI[6] file. Valid matrix names contain only alphanumeric characters, spaces, and underscores (_). If matrix names have spaces, then you must include the entire MI matrix reference in double quotes to recognize the name. For example:

MW[1]="MI.1HBW TRIPS"

On the FILEI statement the subscript is either explicitly, or implicitly, specified. MATI=… defaults to MATI[1], and MATI[3]=name3,name4,name5 sets up MATI[3], MATI[4], and MATI[5]. Since it is required that ZDATI files have variables explicitly defined for them, the vector form of ZDATI (ZDATI=file1, file2…) will be treated as an error.

When an input file is used in an expression, it may have an additional subscript appended to it to specify a zone number. For matrices, the subscript references the column within a row, and for zonal data, it references the nth item in the vector. Zonal data can be viewed as having zones rows with one column per zone, or as one row having zones columns (user’s choice, it doesn’t matter). If there is no subscript specified, the current value of J is used. J will always be in the range 1-zones. Example: MI.6.3[I] accesses the intrazonal cell. ZI.1.TRMTIME[I] and ZI.1.TRMTIME[J] reference the origin and destination terminal times, respectively.

Matrices can be input as either binary matrices or as data on ASCII or DBF type records. In the latter case, PATTERN and FIELDS must be specified. ASCII type records are more subject to variation (empty fields, invalid values, etc.), and the program is a bit more tolerant with them. If a J or M is out of range, the values for the field are ignored. On the other hand, if the field contains non-numeric data, it is treated as an error, and further processing of the record is terminated.

The FILEI file keywords ZDATI, RECI, and DBI can point to elements in a multidatabase (MDB) file by designating the filename followed by a backslash and the element name. The program will generate a temporary file of records, each record containing all the variables in the element. If the FILEI file keyword value is followed by variable definitions, those definitions are ignored, or in some cases, cause a fatal termination. On a ZDATI file name, you can specify a definition for Z to indicate which MDB element represents the zone number. Z= is not necessary if one of the element variables has an appropriate name for the zone number (see description of ZDATI for details).

Note: CUBE 6.4 does not support EMME/2 data bank files.

FILEI Keywords

  • DBI - |KF9| - Name of a DBF file, MDB data element, or an ASCII record file with either delimited (separated by a space or a comma or combination of both space and comma) or fixed format records.

    If you specify a DBF file, the program recognizes the file and the fields. Reference the field names in the DBF header directly in the script as DI.#.fieldname. Do not explicitly define the variables in the DBI statement.

    If you specify an MDBelement file and name, the program recognizes the file and the fields. Reference the field names in the MDB data element directly in the script as DI.#.fieldname. Do not explicitly define the variables in the DBI statement.

    If you specify an ASCII record file, define all variables that you want the program to recognize DBI.#.name in the DBI statement, using the appropriate keywords.

    ASCII record files are either a fixed format text file (fixed field locations and lengths), or free format. You must indicate which format is used in the definition of each field. Indicate free format with field definitions containing a single number. Indicate fixed format fields by using name=lo[-hi] or field=lo[-hi] syntax, where lo is the first column number of the field and hi is the last column. (Indicate a single-column character with the hi column number the same as the lo column number.)

    Define a field as a character variable by appending “(C)” to the name. For example, TITLE(C)=1 would define the variable named DI.#.TITLE as a character variable, and would read the data from the first data field in the input file.

    You can specify the delimiters for free-format records using the DELIMITER keyword.

    The following special variables are available for all file formats:

    DBI.# — String variable containing the full data record

    DBI.#.JOINCOND — - Integer indicating the status from a JOINTODBI action, i.e. when the "Join To" DBI file is moved to a different record. The return value is the same as the return code for the DBISeek function:

    • 0 = a match was found

    • 1 = error (not common)

    • 2 = match not found and the current record is the next higher key record

    • 3 = match not found and the search for key is greater than the last record; the current record is the last record

    • -1 = no match found within in the chain of joins; the current record is not changed

    DBI.#.NUMFIELDS — Number of defined data fields DBI.#.NUMRECORDS — Number of data records in file

    DBI.#.RECNO — Number of the currently processed record

    Different arrays are available. Each array is dimensioned as [DBI.#.NUMFIELDS]. All the values (except Name and Type) are updated each time the record is processed. The arrays are:

    • DBI.#.CFIELD — String value for the field (Null if DBI.#.TYPE=’N’)

    • DBI.#.FIELDERR — 1 if the field had a format conversion error

    • DBI.#.FIELDERRCNT — Cumulative count of errors for this field.

    • DBI.#.NAME — Name of the field

    • DBI.#.NFIELD — Numeric value for the field (0 if DBI.#.TYPE=’C’)

    • DBI.#.TYPE — Type of field (either ‘N’ for numeric or ‘C’ for character

    See More on DBI.

  • DBI - AUTOARRAY - |S| - Designates the name(s) of the field(s) that are to be stored in arrays with the specified name. An array for each named field will be generated and populated with values from the DBI records. If you enter a value of "ALLFIELDS," all the fields will be placed into arrays (no other names need be supplied).

    You can reference each array as DBA.#.name[Index], where Index may be 0-DBI.#.NUMRECORDS. If Index is less than 0 or greater than NUMRECORDS, the value in DBA.#.name[0] is used. By default, the value at ARRAY[0] will be 0 for numeric fields and NULL for character fields. You can provide a substitute value for invalid Index processes, such as DBA.1.Name[0] = ‘ERROR’ or DBA.1.Name[0]=999999. Note that if the name is included in a SORT, [0] will be revised during the SORT, because the SORT routine uses that cell for temporary storage.

  • DBI - AUTOMDARRAY - |S| - FILEI DBI[]=, TYPE=, AutoMDArray=, Indexes=fld-size,fld- size,fld-size, ArrayFields=fld,fld,fld

    This will load database or text file data into arrays before any script processing. This is very similar to the current AutoArray capability but can be used to load data into multi dimension arrays. The AutoMDArray keyword is used to define the array name.

    The TYPE keyword is the same as the TYPE keyword in the ARRAY statement for declaring the data type/size of the array. All AutoMDArray defined after the TYPE keyword will have the same type as specified by the TYPE keyword. Data from the DBI record will be converted to a form that is compatible with the array type (e.g. string to numeric).

    With no Indexes or ArrayFields specified, the DBI file is loaded into a 2-dimension array, the first dimension is the record number and the second dimension is the field number.

    With the ArrayFields keyword, selected fields can be loaded into the array. If there are 2 ArrayFields, then the second dimension will have a size of 2. The special field name DBI.RECNO can be included to add a field that contains the record number of the DBI record.

    If the data file has only one field or if only one field is specified in the ArrayFields keyword, then the array will have one less dimension because there will be no need to have an extra dimension to hold multiple fields of data.

    With the Indexes keyword, some of the fields in the record can be used as array indexes to populate the array. A size value must be specified for each Indexes field and it should be large enough to accommodate the largest index value. Any records with an index value large than the stated size will not be loaded into the array. This feature can be used to load only selected records into the array. For example:

    FILEIDBI[x]=xxx, AutoMDArray=name3, Indexes=fld1-10,fld2-20,fld3-30, ArrayFields=fld4,fld5,fld6,DBI.RECNO
    		  

    In this case, name3 will have 4 dimensions (10x20x30x4), the values in fld1, fld2 and fld3 determines the indexes for the first 3 dimensions and the fld4, fld5, fld6 and DBI.RECNO values will go into 4th dimension. If the field values in record 3 are:

    fld1=11 fld2=12 fld3=13 fld4=14 fld5=15 fld6=16

    then:

    name3[11][12][13][1]=14, name3[11][12][13][2]=15,
    name3[11][12][13][3]=16, name3[11][12][13][4]=3

    Another example:

    FILEI DBI[x]=xxx, AutoMDArray=name3, ArrayFields=fld1,fld2,fld3

    In this case, name3 will have 2 dimensions, the record number is the index for the 1st dimension and the fld1 value will go into index 1 of the 2nd dimension. If the field values in record 3 are:

    fld1=11 fld2=12 fld3=13

    then:

    name3[3][1]=11, name3[3][2]=12, name3[3][3]=13

    This form can be used to replace multi-key discrete lookup tables. It will be easier and faster.

  • DBI - DELIMITER - |S2| - Use to specify two different controls for free-format records.

    DELIMITER[1] specifies the field-separator characters. The default values are " ,t"; where t is used to designate a tab:

    DELIMITER[1]=" ,t"

    DELIMITER[2] specifies escape-character sequences that permit field-separator characters in free-format records. Specify characters in pairs, the character that marks the start of an escape sequence along with the character that marks the end of an escape sequence. Upon encountering the starting escape-sequence character, CUBE Voyager treats all subsequent data as part of the same record until it encounters the ending escape-sequence character, even if it encounters a field-separator character. The default value specifies single quotes, double quotes, parenthesis, brackets, and braces as escape character sequences:

    DELIMITER[2]="""''()[]{}"

    Note: You must enclose the entire value in double quotes or single quotes.

    If you include a single space as the last character in DELIMITER[2], CUBE Voyager will remove the leading and trailing character from any string it reads.

    The starting escape-sequence character in DELIMITER[2] cannot be a field-separator character in DELIMITER[1].

    You can specify both DELIMITER[1] and DELIMITER[2] in one expression: Specify DELIMITER= followed by two values enclosed within quotes and separated by a space or a comma.

    CUBE Voyager automatically removes leading spaces from all fields, unless the field is enclosed in an escape-character sequence and DELIMITER[2] does not contain a space as its last character.

    Example

    Suppose you set a comma as field-separator and double quotes as an escape sequence:

    DELIMITER=',''""'

    When reading the following input data:

    JohnSmith,"Oakland, CA",USA

    CUBE Voyager reads three fields: "John Smith," "Oakland, CA,"and "USA."

  • DBI - FIELDS - |IPV| - An optional method for defining data fields in the input file. Used only when the DBI records are fixed or free format. If this keyword is present, only the fields specified will be extracted.

    The values specify the columns or fields of the DBI file records where a desired field is located. If a data field (FIELDS= or name=) is defined by a pair of numbers (lo-hi), that sets the format as fixed. If a data field is defined by a single number (field number on the records), that sets the format as freeform. All data fields must be defined in the same format.

    For example:

    FIELDS=1-5,6-10,21-25

    Specifies that the data is fixed format and DBI.#.NFIELD[1] is in columns 1-5, DBI.#.NFIELD[2] is in columns 6-10, and DBI.#.NFIELD[3] is in 21-25.

    FIELDS=6,9,13

    Specifies that the data is in free format and defines DBI.#.NFIELD[1] comes from field number 6, DBI.#.NFIELD[2] comes from field number 9, and DBI.#.NFIELD[3] comes from field number 13.

    Optionally, FIELDS can specify multiple successive fields with a single specification (providing all fields are the same type, N or C).

    For example:

    FIELDS=6(7)

    Specifies that DBI.#.NFIELD[1]…DBI.#.NFIELD[7] will be obtained from fields 6 through 13 of the data records.

    FIELDS=6(C7)

    Specifies the same, but those fields would all be character values.

    You can reference these field values as DBI.#.NFIELD[#], DBI.#.CFIELD[#] or as DI.#.FIELD# in script statements.

  • DBI - JOINTODBI - |I| - Specifies the number of the input DBI file to join this DBI file to. If JOINTODBI&& is specified for a DBI file, then the **SORT keyword must also be specified. The field names referenced by the SORT keyword define the join key. You must also specify the JOINTOFIELDS subkeyword.

    You can use the DBI.#.JOINCOND variable to check the status of the join action, i.e. when the "Join To" DBI file is moved to a different record.

  • DBI - JOINTOFIELDS - |SV8| - Specifies the fields on the file referenced by JOINTODBI that corresponds to the join key fields identified by the SORT keyword. This keyword can have fewer referenced field names than the SORT keyword but cannot have more than the number of sort keys.

    For example:

    FILEI DBI[1] = "TRIPRECORDS.DBF",
    SORT=HHNO,PERSNO TRIPNO
    FILEI DBI[2] = "PERSON.DBF",
    SORT=HHID,PERSID JOINTODBI=1
      JOINTOFIELDS=HHNO,PERSNO

    In this example, DBI file 2 is a person-level survey record file. This file contains the fields HHID and PERSID, which uniquely identify the person record, along with other household and person-level demographic data fields. DBI file 1 contains the person-level trip records from a travel survey. This file contains the fields HHNO, PERNO, and TRIPNO, which uniquely identify each person-trip record, along with other trip-related data fields. Note that the key field name on which the join is performed does not need to match in the two files. With the files joined, script statements that process a trip record are linked to the corresponding person-level data file, enabling trip-based computations to directly reference the household and person-level characteristics in the joined file.

  • DBI - MAXRECS - |I| - Limits the number of records read from the DBI file. If the DBI is not a DBF file, the program treats both zero length and blank records as legitimate records. If the file is a DBF file, deleted records (flagged with a "*") are not counted as records.

  • DBI - NAME - |IP| - Name of a variable to extract from a text format record. The value contains the location of that variable on the data record.

    You can reference the variable in other parts of the script as DI.#..name. If the name has "(C)" appended to it, the variable type is character. If the name has nothing—or "(N)"— appended, the variable type is numeric.

    The value must be either a single integer, or a pair of integers (separated by a dash). If the records are in free format, the values must be single integers indicating the field number in the data record. If the input records in fixed format, the value will be lo-hi; if the field is a single column, it must be designated as lo-hi, where lo=hi = the column number of the data field.

  • DBI - SORT - |S9| - Designates that the input records are to be processed in a specified sorted order. The values are the names of the variables that the sort is based upon. There may be up to nine sort keys. If a sort name is preceded by a minus (-) sign, that field is to be sorted in descending order. If there is no leading sign, or there is a preceding plus (+) sign, that field is to be sorted in ascending order.

    Note that SORT can reference the field names created using FIELDS under the current FILEI DBI. In this case the DI prefix is not needed.

    For example:

    FILEIDBI[1]="{FixedFormat}",
    DELIMITER=' ', FIELDS=1(8),
    SORT=FIELD3

    Here, the SORT is performed on the third field (of eight) declared in the DBI statement.

  • LOOKUPI - |FKV999| - Name of file containing records for a lookup function implemented with the LOOKUP control statement.

    Equivalent to the FILE keyword of the LOOKUP control statement. You must index LOOKUPI.

  • MATI - |KFV20| - Specifies the input files with matrix data. If the file specifies a CUBE Voyager, TP+, MINUTP, or Tranplan binary matrix file, or a standard data base (DBF) file, the program will automatically detect it. If it is not detected as one of those, it is assumed to be an ASCII text file. If it is not a binary matrix file, PATTERN and FIELDS must be associated with the MATI.

    MATI can process matrix files of any size, subject to available system memory and storage.

  • MATI - AUTOMDARRAY - |S| - FILEIMATI[]=,AutoMDArray=,MI=,I=,J=,RESTRICTION=

    This will load matrix data into multi-dimensional arrays before any script processing. Selected tables can be loaded into arrays. If only one table is selected, it will be loaded into a 2 dimension array. If multiple tables are selected, then they will be loaded into a 3 dimension array with the first index being the table number. For example:

    FILEI MATI[x]=xxx, AutoMDArray=name1, MI=4,6-8

    will load the matrix file table 4 to array name1[1][i][j], matrix file table 6 to array name1[2][i][j] etc. The same table number can be specified multiple times to load the same table into different part of the array. The list of input table numbers do not need to be in order (e.g. MI=6-8,4) but a range pair must be specified in low-high order.

    Selected I’s and J’s can be loaded into a smaller array. For example:

    FILEI MATI=xxx, AutoMDArray=name2, MI=4, I=11-15,21-25, J=31-35,41-45
    		  

    will load parts of the matrix file table 4 to a 10x10 array with name2[1][1] = matrix[11][31], name2[6][7] = matrix[21][42], name2[10][10] = matrix[25][45] etc. The same I/J number can be specified multiple times to load the same I/J into different part of the array. The list of input I/J numbers do not need to be in order (e.g. I=6-8,4) but a range pair must be specified in low-high order.

    Additional restrictions can be applied when loading the matrix data. The RESTRICTION keyword can have a combination of the following values:

    LOWER – only load the lower part of the matrix (I < J)

    UPPER – only load the upper part of the matrix (I > J)

    DIAGONAL – only load the diagonal part of the matrix (I = J)

    IJ – applies the LOWER, UPPER, and DIAGONAL filter based on the original IJ number from the input matrix table

  • MATI - FIELDS - |S| - Specifies the data fields to be read from an input record. Any one (and only one) format may be used to specify the fields. If the MATI file is a database file, the values in FIELDS must be names found in the dbf dictionary. A range of names (name-name) may be used to specify a string of consecutive fields.

    If the file is not a DBF, its format may be either fixed or variable; the first field definition establishes the format. If the first field value is a number, the format will be fixed; if it begins with a letter (not a digit), the format will be variable.

    With variable format, every field value must end with a number (only the first field value is required to have a leading non-digit). Ranges of variable format fields may be specified. For example: #4-6,10,13,2. A leading # is recommended for variable format, although any character string is acceptable. The program extracts the number from the right end of the definition; leading non-digits are ignored.

    With fixed format, the field values define the positions on the record where a data field is located. The field values may be entered as single values (single column), pairs of numbers (beg-end), or as a group of three (beg-end-numflds) to indicate a series of equal length fields. Example: FIELDS=1-3,6-8,10,11-20-8. For a PATTERN=IJM:V, this example would indicate that I is in columns 1-3, J is in columns 6-8, M is in column 10, and eight data fields (each 10 characters wide) are in columns 11-20, 21-30,etc. (Note: When reading with fixed format, the highest begin column number may not exceed 2047. For example, for a record longer than 2047 bytes, FIELDS=1-10-204 is OK, while FIELDS=1-10-205 will get a warning because the program is unable to read in the last field. This limit is not applicable to variable format files.)

    When the field value of M is set to zero, it indicates that the starting matrix number is not included in the input data, hence, implied, and the matrix number always starts at one for each record. The specification of FIELDS with implied matrix number will be shown in the example in the next section.

  • MATI - PATTERN - |S| - Sequence of letters that specifies how the program processes the associated text or DBF MATI file. The pattern has two portions separated by a colon: a base portion and a repeating portion.

    In the pattern definition:

    • There must be a single I, J, and V. I must be the first letter in the base portion, and V must be in the repeating portion.

    • There may be one M to specify the starting matrix number. If there is no M, matrix 1 is assumed. The highest M that the program recognizes is 255.

    • If there are multiple characters in the base portion, the last character in the base portion indicates which variable is incremented for each repeating set.

    Valid combinations are:

    IJ:V — I J values for J,J+1,J+2… IMJ:V — I M J values for J,J+1,J+2… IJM:V — I J M values for M,M+1,M+2… I:JV— I sets of J and V I:VJ — I sets of V and J IJ:VM— I J sets of V and M IJ:MV — I J sets of M and V IM:JV — I M sets of V and J IM:VJ — I M sets of J and V I:JVM — I sets of J, V, and M I:JMV — I sets of J, M, and V I:MJV — I sets of M, J, and V I:MVJ — I sets of M, V, and J I:VJM — I sets of V, J, and M I:VMJ — I sets of V, M, and J

    This method allows CUBE Voyager to read any commonly encountered input format. It is necessary to have FIELDS specified in conjunction with PATTERN. The above examples assumed that the FIELDS values implied variable format and that there was an appropriate number of FIELDS values specified. If the values specified in FIELDS do not align correctly with the PATTERN, a warning message is issued. When reading a data record, the program aligns the next FIELDS value with the next letter in the PATTERN, and extracts the data. When the PATTERN is exhausted, the reading continues from the beginning of the repeating portion of the PATTERN. This continues until the FIELDS list is exhausted. If the FIELDS list is exhausted before the end of the PATTERN, reading is terminated without storing the last repeat value.

    Note that the data values need not be read in sequential order from the input records. The FIELDS values can be used to specify any order.

    See More on MATI PATTERN.

  • MATI - SKIPRECS - |I| - Instructs MATRIX to skip over a number of records in the input file before processing the data records. This is useful when the file has header line(s) which do not contain data.

    For example:

    MATI[1]=Inputs.CSVPATTERN=IJ:VFIELDS=1-10-202SKIPRECS=2

    In this case, the first two records (rows of data) in Inputs.CSV will be ignored when processing the file.

  • RECI - |KF| - Name of a DBF file, an element in a multidatabase file, or an ASCII record file with either delimited or fixed format records.

    Note: RECI can process up to 32,000 characters per record (or ‘row’ of the data file). If there are more than this, MATRIX will issue an error message. Note also that CUBE Voyager might not properly process database files larger than 2 GB.

    For text files, you must define all variables that the program will recognize (RI.name) in the FILEI RECI statement using the appropriate subkeywords. For DBF or MDB files, the program recognizes field names in the DBF or MDB header; do not explicitly define the variables in the FILEI RECI statement. You can reference these fields directly in the script as RI.fieldname.

    For text files (files other than DBF or MDB files), use the first variable to indicate the file format, either delimited (free format, separated by commas or spaces) or fixed format. Define the first field as a single number to indicate delimited format. Define the first field as name=lo[-hi] or field=lo[-hi] to indicate fixed format (where lo is the first column number of the field and hi is the last column). For single-column characters, you must designate the hi column as the same as the lo column. To define a variable as a character variable, append "(C)" to the name. For example, TITLE(C)=#1 would define the variable named TITLE as a character variable; the program consider data read from the first data field on the input file to be character data.

    You can also specify the delimiters for delimited records with the DELIMITER keyword.

    If there are any RECO statements, all RECI variables (RI.name) on the input file are automatically copied into equivalent RO.name variables immediately when a record is read. The RI.variable attributes are ported to the corresponding RO.variables. Only variables with the RO.prefix can be written to the RECO file.

    The following special variables are available to the user for all file formats:

    RECI — String variable containing full data record RECI.NUMFIELDS — Number of defined data fields

    RECI.NUMRECORDS — Number of data records on the RECI file

    RECI.RECNO — Number of the current record being processed

    The program also makes four different arrays available to the user. Each array is dimensioned as [RECI.NUMFIELDS]. The arrays are:

    RECI.NAME — Name of the field

    RECI.TYPE — Type of field (either ‘N’ for numeric or ‘C’ for character

    RECI.NFIELD — Numeric value for the field (0 if RECI.TYPE=’C’)

    RECI.CFIELD — String value for the field (Null if RECI.TYPE=’N’)

    The NFIELD and CFIELD values are updated to the values from each record as the record is read.

    If a RECI statement is present, the program enters a record processing loop instead of the traditional I-loop. Thus, MATIs are not read unless a MATVAL function is used, and FILEO MATO keywords should not be used. As each RECI record is read, it is processed against the script statement stack. The PRINT statement allows the user to write out any portion of the input record plus any computed variables.

    The record processing loop sets I=1 and reads records until the end of file is found where it sets I=0. To test on end of file the IF (I=0) condition can be used.

    See More on RECI for some examples.

  • RECI - DELIMITER - |S2| - Used to specify two different controls for free-format records.

    For details, see DELIMITER description under DBI keyword on page 598. Usage of DELIMITER is the same under both keywords.

  • RECI - FIELDS - |IPV| - This is an optional method to NAME for defining data fields on the input file and it is used only when the RECI records are fixed or free ascii format. If this keyword is present, only the fields specified will be extracted. The values specify the columns or fields of the RECI file where a field is located. If a data field (FIELDS= or name=) is defined by a pair of numbers (lo-hi), that sets the format as fixed. If a data field is defined by a single number (field number on the records), that sets the format as freeform. All data fields must be defined in the same format.

    For example: FIELDS=1-5,6-10,21-25 specifies that the data is fixed format and RECI.NFIELD[1] is in columns 1- 5, RECI.NFIELD[2] is in columns 6-10, and RECI.NFIELD[3] is in 21-25. FIELDS=6,9,13 specifies that the data is in free format and will define RECI.NFIELD[1], RECI.NFIELD[2], and RECI.NFIELD[3] coming from data fields number 6, 9, 13 respectively.

    Optionally, FIELDS can specify multiple successive fields with a single specification (providing all are the same TYPE, N or C). FIELDS=6(7) specifies that RECI.NFIELD[1]...RECI.NFIELD[7] will be obtained from fields 6 through 13 of the data records. FIELDS=6(C7) would be the same, but those fields would all be character values.

    These fields can either be referenced as RECI.NFIELD[#], RECI.CFIELD[#] or as RI.FIELD# in stack statements.

    Up to 16,384 fields may be defined.

  • RECI - LISTERRS - |?| - Flag that indicates if errors should be listed to the run print file. Default value is F. If LISTERRS=T then MAXERRS automatically defaults to MAXERRS=1000. This is to prevent excessive listing of error messages to the run print file. If the user wishes to see more than 1000 error messages in the run print file then he must explicitly code the MAXERRS value desired.

  • RECI - MAXERRS - |I| - Maximum number of errors allowed in reading the RECI records before a fatal error message is returned. Default value is no limit. The default setting will not return a fatal error message no matter how many errors are detected.

  • RECI - MAXRECS - |I| - Places a limit on the number of records to be read in from the RECI file. Default value is no limit.

  • RECI - MAXSCAN - |I| - Allows the user to limit the file sampling for text records in order to reduce front end time on very large files. The program normally scans the entire file to obtain the longest record, the number of records, the maximum length of each field, etc. That could be quite time consuming, and not really productive for very large files such as the census files. If the user is certain that all the records are the same length, the use of this keyword can reduce front end time. This value will be used only if the format is fixed, and there is no SORT specified. The value must be >= 10, if specified. This control should not generally be used and was added primarily for internal Bentley use. I maybe save time if processing very large data files.

  • RECI - NAME - |IP| - Name of a variable to be extracted from a text format record and the value will be the location of that variable on the data record. It can be referenced in all other parts of the script as RI.name. If the name has "(C)" appended to it, the variable will be considered as character. If it has nothing, or "(N)", appended, the variable will be considered numeric. The value must be either a single integer, or a pair of integers (separated by a dash), to designate where the variable will be obtained from each record. If the records are read in free format, the values must be single integers indicating the field number on the data record. If the input records are read in fixed format, the value will be lo-hi; if the field is a single column, it must be designated as lo-hi, where lo=hi= the column number of the data field.

  • RECI - SORT - |S5| - Designates that the input records are to be processed in a specified sorted order. The values are the names of the variables that the sort is based upon. There may be up to five sort keys. If a sort name is preceded by a minus (-) sign, that field is to be sorted in descending order. If there is no leading sign, or there is a preceding plus (+) sign, that field is to be sorted in ascending order.

    Note that SORT can reference the field names created using FIELDS under the current FILEI RECI. In this case the RI prefix is not needed.

    For example:

    FILEI RECI="{FixedFormat}",
    DELIMITER=' ', FIELDS=1(8),
    SORT=FIELD3
    		  

    Here, the SORT is performed on the third field (of eight) declared in the RECI statement.

  • ZDATI - |KFV10| - Specifies the input files containing zonal data. There can be up to 10 zonal data files. Zonal data is data which is specific for each zone. Every zonal record must include a field that identifies the zone to which the record data applies. Aside from the zone number, any fields from the record can be extracted and used by the program.

    The file format can be: ASCII, DBF, MDB, or a CUBE Voyager binary network. The program will try to detect what type of file it is. If it cannot identify the file as a DBF, MDB, or a CUBE Voyager network, it will assume ASCII. When the program detects a CUBE Voyager network file, it opens the node database portion of the file as zonal data.

    If the file is of ASCII format, the fields to be extracted must be named and identified on the ZDATI statement by either relative field number, or by exact column positions on the records. The field that contains zone number must be specified using ‘Z=’ keyword.

    If the file is a DBF, MDB, or a CUBE Voyager network, it is not necessary to name the fields to be extracted. All fields will be extracted and can be referenced, in the script, by existing field names from the input file. (DBF field names up to 11 characters long may be input). The specification of zone number field is optional for those two file formats. If ‘Z=’ is present, the specified field will be used to extract zone number. Otherwise, the program will try to determine the zone number field based on file type. For DBF or MDB files, the program will go through all field names to find a match with one of the following possible zone field names, in the given order: {Z, I, J, ZONE, ZONA, TAZ}. The first matched name will be used to extract zone number. (Note: For files with more than one possible zone field from the list above, it is recommended to specify zone number field explicitly to ensure the correct field is used.) For CUBE Voyager network files, node numbers (N) will be used as zone numbers by default.

    ZDATI can contain string data fields. Where fields cannot have their type automatically determined such as NET, MDB or DBF files, require the type to be specified with the parameters. Character fields must have the "(C)" suffix appended to be treated as string input. E.g. FILEI ZDATI[2] = "EITrips.csv", OID_=#1,Z=2,EITRIPS=3,NAME(C)=4

  • ZDATI - AVE - |SV| - Average of all records.

  • ZDATI - AVEX0 - |SV| - Average of all records, where the value from the file records is not 0.

  • ZDATI - CNT - |SV| - Count of the records that contain the variable.

  • ZDATI - DEFAULT - |R| - Value with which to initialize the array for the named variable. Then, if there are no records for a zone, or the field is blank on a record, this value will be used.

    The following keywords indicate a process to use in obtaining the value for the variables that are listed following the keyword when there is more than one record per zone. The values for the variables will be obtained only from file records that contain the variable. A variable may appear in only one keyword list; any variables that are not in any list will be set to LAST.

  • ZDATI - FIRST - |SV| - Directly from the record from the FILEI with the lowest index [].

  • ZDATI - LAST - |SV| - Directly from the record from the FILEI with the highest index [].

  • ZDATI - MAX - |SV| - Maximum value of all the records.

  • ZDATI - MIN - |SV| - Minimum value from all the records.

  • ZDATI - NAME - |S| - Identifies a data variables that is to be extracted from each record. Only the variables named will be extracted. If the file is a dbf, the value for each name is the name from the DBF dictionary. In most DBF cases, name=name would be the standard, but it is not necessary to keep the same names. For text files, the value assigned to name is either a field number (delimited format), or the columns (fixed format) where the variable is located on the record. All names must be specified with the same format; the first name value (including Z) establishes the format. If the first value is a number, fixed format is assumed; otherwise, delimited format is assumed. If delimited format is specified, each name value MUST end in a number. It doesn’t matter what string precedes the number (the value need not be prefixed with a string). Example: Z=#1,POP=#2, AREA=3, SALES=xxx4. These are all be valid, because Z specified triggered delimited format. Z=1-5,POP=#2 would be invalid because Z specifies fixed format.

  • ZDATI - SELECT - |S3| - Used to cause selective reading of zonal data records from ASCII files. The program will compare a field from each record with the string specified in SELECT[1], and if the comparison fails, the record is bypassed. This selection is not used if SELECT is not specified. SELECT[2] specifies the input record field whose value is to be compared with the value of SELECT[1]. If SELECT[2] is a number, it designates the beginning column of the comparison field on the input record, and SELECT[3] can be optionally specified to designate the ending column. SELECT[2] and [3] must both be numeric and should be separated by a dash. Alternatively, if SELECT[2] is not numeric, but ends with a number (first example), it is assumed that the value indicates a relative field number on the data record. That field is the comparison string. SELECT[3] is ignored if SELECT[2] is a free field definition.

    SELECT=abc,6-8 select only if columns 6-8=abc

    SELECT=1,#2 select only if a 1 in field no. 2

  • ZDATI - SUM - |SV| - Sum of all the records.

  • ZDATI - Z - |S| - Identifies where the zone number identifier is found on each data record; Z is required for ASCII files and also if a DBF file is being used and one of the special field names :

    {Z, I, J, ZONE, ZONA, TAZ} is NOT in the DBF file.. ‘Z=’ is a special case for ‘name=’.

Caveat: The program establishes a buffer to read file records into. It has to know how long a buffer is required. With DBFs and fixed format records, the required length is known, but with delimited format, the required length can not be estimated exactly. For delimited files, the record length is estimated by multiplying the highest field number by 10. If the estimated length is inadequate, a dummy variable with a high field number can be specified to generate a larger record length.

More on DBI

DBI files are not automatically processed. You must write scripts to read the records. Several functions are available to read the records. Use these functions in a COMP statement with the form: N=DBIfunc(DBI#,…). DBI# must always be the first argument. All the functions return a value to indicate the success of the operation. A return value of 0 indicates a successful operation; any other value indicates the read was not 100% successful. You must check the return code. The functions are:

  • DBIReadNext(#,R) where R indicates the record to read, specified relative to the current record. A negative R means prior to the current record, and a positive R means after the current record. Write sequential reads as DBIReadNext(#,1), though DBIReadNext(#) is also allowed. A return code of 1 indicates any of the following errors: bad #, R<1, or R>DBI.#.NUMRECORDS.

  • DBIReadRecord(#,R) where R indicates the record to read. R must be 1 – DBI.#.NUMRECORDS, or the return code will be 1.

  • DBISeek(#, R,…) where R is a value to search for in the field specified as SORT[1]. In order to use this function, there must be at least as many SORT values as there are R arguments. There may be fewer R values than there are SORT fields, but not more. This function searches for the record that matches all the specified R values. The return values are:

    • 0 — A match was found.

    • 1 — An error in setup occurred.

    • 2 — A match was not found, and DBI.#.RECNO is set to the record that is above the R selections.

    • 3 — The R values are greater than the last record and DBI.RECNO is set to the last record.

    In all cases, the DI.#.field values are extracted from the record indicated by DBI.#.RECNO, and the record pointer points to that record.

    See Example 5: DBI processing using JOINTODBI and Example 6: DBI processing using AUTOARRAY for examples of DBI processing.

Note: You can create and populate arrays with just a FILEIDBI statement; you do not need DBIRead functions.

More on MATI PATTERN

Example for MATI[1]

PATTERN Data record fields I M [J] Values
IJ:V 1 15 21 22 23 24 I=1 MI.1.1[15-18] 21,22,23,24
IMJ:V 1 6 18 100 101 105 I=1 MI.1.6[18-20] 100,101,105
I:JMV 5 12 1 8 14 2 90 I=5 MI.1.1[12] 8
  I=5 MI.1.2[14] 90
IJM:V 5 12 3 8 14 2 90 I=5 MI.1.3[12] 8
I=5 MI.1.4[12] 14
I=5 MI.1.5[12] 2
I=5 MI.1.6[12] 90

The above PATTERNS do not provide for the situation where the record contains I, J, then multiple values to represent matrix 1, 2, 3… In this case, the PATTERN IJM:V, with the FIELD value of M set to zero, can be used to describe the input data. The matrix number is implied and always starts with 1 on each record. The following example illustrates the specification of PATTERNS and FIELDS for input data with implied matrix number:

Example (implied matrix number)

(input data record)

1 15 21 22 23 24
(CUBE Voyager script)
MATI[1]=input.txt, PATTERN=IJM:V, FIELDS=1-2,3-4,0,5-7-4
  ; fixed format
or
MATI[1]=input.txt, PATTERN=IJM:V, FIELDS=#1,2,0,3-6
  ; variable format
or
MATI[1]=input.dbf, pattern=IJM:V,
FIELDS=I,J,0,V1,V2,V3,V4; DBF format
; The input dbf in this example would have the named
; fields I,J,V1,V2,V3,V4
(results)
I=1, J=15, MI.1.1=21, MI.1.2=22, MI.1.3=23, MI.1.4=24

The above PATTERNs also do not provide for the situation where the record contains I, then multiple values to represent J values 1, 2, 3… for a single matrix (implied matrix number M=1). In this case, the PATTERN IJ:V, with the FIELDS value of J set to zero, can be used to describe the input data. The J value is implied and always starts with 1 on each record. The following example illustrates the specification of PATTERN and FIELDS for input data with implied J number:

Example (implied j index number)

(input data record)

1 37.3912    54.5413  6.8414 14.5015
2 167.1612  269.2513 35.5314 75.1215
3 13.0612    22.1213  4.8514 10.6815
4 31.6512    54.2813 12.2914 31.3815

This example data represents a 4 zone matrix with the I values in column and the cell values for the implied J zones in columns 2 through 5. The script example below will build a binary matrix using the implied J values.

RUN PGM=MATRIX
FILEI MATI=temp1.DAT  PATTERN=IJ:V FIELDS=#1,0,2-5
FILEO MATO=temp1.mat  MO=1
PAR ZONES=4
MW[1]=mi.1.1
ENDRUN

More on RECI

Example RECI statements:

FILEI RECI=myfile.dbf,
FILEI RECI=myfile.mdb\mytable, SORT=key2, -key1, +key6
FILEI RECI=myfile.txt, nvar1=1-3, nvar2=5-8, cvar3(c)=10- 10, SORT=nvar2, cvar3
FILEI RECI=myfree.txt, nvar1=1, cvar2(C)=2, cvar3(C)=3,
DELIMITER[2]='//'
FILEI RECI=myfree.txt, nvar1=1, cvar2(C)=2, cvar3(C)=3,
DELIMITER[2]='""'' '
FILEI RECI=myfree.txt, nvar1=1, cvar2(C)=2, cvar3(c)=3,
DELIMITER=' ,;t' , '//() ' SORT=-nvar1,+cvar3

Example of usage: to sum all the housing units in a record (even if the exact names are not known, but we do know that all units fields are named xxUNITS):

TotUnits=0
Loop k=1,RECI.NUMFIELDS
If (RECI.TYPE[K] = 'N' && substr(RECI.NAME[k],3,5) =
'UNITS') TotUnits = TotUnits + RECI.NFIELD[K]
EndLoop

Example:

In a record processing run of matrix

VAR1TOTAL=VAR1TOTAL+VAR1
IF (I=0)
VAR1AVG=VAR1TOTAL/RECI.NUMRECORDS
PRINT LIST=RECI.NUMRECORDS,VAR1TOTAL,VAR1AVG
ENDIF

would sum the values of the variable VAR1 and once all records have been read (I=0) compute the average value of VAR1 and print to the report file the number of records, the total of VAR1 and the average of VAR1

Example:

RUN PGM=MATRIX
FILEI RECI=network_link.dbf
PARAMETERS MAXSTRING=100
if (RI.A>25 & RI.B>25)
print, list=ri.A,',',ri.B,',',ri.ROAD_TYPE,',',
ri.IMPORTANCE,',',ri.ROAD_NAME,',',
ri.CLASS,',',ri.SPEED,',',
ri.PICTUREFIL file=tmp1.csv
endif
if (I=0)
print list='Number of link records=',
RECI.NUMRECORDS file=tmp2.dat
endif
ENDRUN

Example:

copy file = junk.txt
11 22 33 44 55 66 77 88 99 aa bb cc dd 56 78 90 12
aa bb cc dd 56 78 90 12
endcopy

RUN PGM=MATRIX
;get 1st 5 data fields as numeric fields and also as character fields
FILEI RECI = junk.txt,Fields=1(c5),1(n5)
FILEO RECO[1]=junkout.dbf FIELDS=reci.allfields
FILEO PRINTO[1]=junkprn.prn

write reco=1

print printo=1 form=5lr,list='\nRecno=',reci.recno,'
NumFields=',reci.numfields,
' highest field=',reci.fields,' lng=',reci.lng

print printo=1 form=5lr,list=reci,'\ncfield[1-5] =',
reci.cfield[1],'..',reci.cfield[2],'..',reci.cfield[3],'..',
reci.cfield[4],'..',reci.cfield[5],'..\nnfield[6-9] =',

reci.nfield[6],'..',reci.nfield[7],'..',reci.nfield[8],'..',

reci.nfield[9],'..',reci.nfield[10],'..\nri.field1..5 =',

ri.field1,'..',ri.field2,'..',ri.field3,'..',
ri.field4,'..',ri.field5,'..\nri.field6..10=',

ri.field6,'..',ri.field7,'..',ri.field8,'..',
ri.field9,'..',ri.field10,'..'
endrun

Results of the PRINTO file from the above example:

Recno=1 NumFields=10 highest field=5 lng=50
11 22 33 44 55 66 77 88 99 aa bb cc dd 56 78 90 12
cfield[1-5] =11..22..33..44..55..
nfield[6-9] =11..22..33..44..55..
ri.field1..5 =11..22..33..44..55..
ri.field6..10=11..22..33..44..55..
Recno=2 NumFields=10 highest field=5 lng=23
aa bb cc dd 56 78 90 12
cfield[1-5] =aa..bb..cc..dd..56..
nfield[6-9] =0..0..0..0..56..
ri.field1..5 =aa..bb..cc..dd..56..
ri.field6..10=0..0..0..0..56..

Example of FILEI statements

These statements show various examples of FILEI usage:

FILEI MATI=test11.dat,test12.dat ; MINUTP binary matrix files
MATI[4]=tppltrips.mat  ; TPP or MINUT matrix file
MATI[5]=external.txt,  PATTERN=IJ:V, FIELDS=1-4,6-8,11-10-20
MATI[6]=external.var,  PATTERN=IJM:V FIELDS=#1-30
MATI[7]=external.dbf,  PATTERN=I:JMV FIELDS=ORG,DEST,MAT,TRIPS
ZDATI[1]=housing.txt,  Z=#1,DU1=#2,DUPLEX=3,MULTI_FAMILY=4,
CONDO=5,RETIREMENT=6 SELECT=abc-1-3 FIRST=DU1, LAST=DUPLEX
ZDATI[4]=pop.txt,Z=1-5,poptotal=6-15,popmale=16-25,popfemale=26-35,
popyouth=36-45,pop19-65=46-55,popsr=56-65

These statements show an example of simple record processing:

copy file=reci_in.txt ; generate input file
A 1 2 3 4 5 6 7 8 9 10
B 1 2 3 4 5 6 7 8 9 10
endcopy
run pgm=matrix
reci=reci_in.txt, FIELDS=1-3 ; switch to record processing mode
; each data record is stored in a string variable "reci"
s2=substr(reci,11,12)
s3='Z'
if (substr(reci,1,1)=='A') s3='B'
; I is the end-of-file indicator
print list=i(3.1), ' ', reci(10), s2, '.', s3, file=out_reci.txt,
print=y
; will result in
; 1.0 A 1 2 3 4 5 6 7 8 9 10.B
; 0.0 B 1 2 3 4 5 6 7 8 9 10.Z
endrun

These statements show an example of getting I-J values from a delimited file:

RUN PGM=MATRIX
RECI = myfile, org=1, dest=2
MATI[1] = mymat; contains time and distance matrices in 1 and 2
If (RI.ORG > 0 && RI.DEST>0)
Time = matval(1,1,RI.ORG,RI.DEST,0)
Dist = matval(1,2,RI.ORG,RI.DEST,0)
Else
Time=0, dist=0
Endif
print file=outfile, list=reci, time(6.2LR), dist(8.2LR)
; duplicate RECI and append time and dist in delimited format
ENDRUN

FILEO

Programs: Distribution, Fratar, Matrix

Outputs data files. Keywords include:

Use FILEO to specify the type and number of output files for the program to produce. CUBE Voyager writes matrix type output files at the end of each I zone.

PRINT statements write formatted print files to the PRINTO file. WRITE statements write RECO files to the referenced DBF file or can point to elements in a multidatabase (MDB) file by designating the file name followed by a backslash and the element name.

NOTE: CUBE 6.4 does not support EMME/2 data bank files.

FILEO Keywords

  • MATO - |KFV20| - Name of an output matrix file. May have an index [x] appended. If you do not specify an index, the program assumes the index is 1. Indices need not be monotonic or sequential. The program can write output matrices in various formats, which you can use with other software.

    MATO may generate matrix (*.mat) files of any size, subject to available system memory and storage.

  • MATO - DEC - |SV*| - Specifies numeric format of values in the output matrix. Specify a separate for each MO. Valid entries vary by file format:

    CUBE Voyager files

    Valid entries include:

    • 0 through 9 — Writes output matrix cells in fixed- point format, preserving the indicated number of digits following the decimal. This is the traditional format for transportation planning matrices.

      Note: CUBE Voyager stores fixed-point format as a decimal-coded integer. If the cell value exceeds the maximum integer value (2,147,483,647), then CUBE Voyager reduces the number of digits stored after the decimal. For example, with =5, CUBE Voyager stores 1,258,756.33715 as the integer 1,258,756,337, which translates to 1,258,756.337.

    • S — Writes output matrix cells in single-precision floating-point format (4 bytes). This format provides seven to eight significant digits (or significant figures). As such, the largest floating point mantissa which can be consistently respresented is 9999999. Additional digits may change from their original value when a program reads them. Certain matrices might require more precision.

    • D — Writes output matrix cells in double-precision floating-point format (8 bytes). This format provides 15 to 16 significant digits (figures)., twice the number when using single precision (S, above).

    If you do not specify , the default value is 2.

    CUBE Voyager processes all matrices in double-precision floating-point format to accommodate a wider range of values and to maintain accuracy and precision. However, writing double-precision numbers to the matrix files might produce very large files. In most cases, a few decimal places for each cell value are adequate.

    For example, for a cell computed as 10/3, the result is 3.33333333… to sixteen digits. If stored as fixed-point with =0, the result is 3, and requires one byte to store. However, this result might not be precise enough for the subsequent uses. If stored as fixed-point with =2, the result is 3.33, and requires two bytes to store. If stored as single precision with =S, the result is accurate to about seven digits, and requires four bytes to store. If stored as double precision with =D, the result requires eight bytes to store.

    MINUTP or Tranplan files

    Do not set . The program ignores the setting and automatically writes 4-byte values, usually integer numbers. You must set the included work matrices to the desired external format before the program writes the matrices. Storing numbers larger than the maximum integer value (2,147,483,647) will result in erroneous values.

    Note: Normally, you round matrices that represent level-of-service (time, distance, cost, and so on), and "bucket round" matrices that represent trips to ensure row totals.

    COMP MW[1]=INT(MW[1]*100+.5) ; LOS rounding
    COMP MW[2]=MW[2]*100, Total=ROWFIX(2) ; bucket rounding

    Optionally, set =S to write a single-precision matrix. However, you cannot use such a matrix as input to CUBE Voyager.

    TRIPS files

    Set to the number of digits after the decimal point (0 to 9). The program stores numbers as integers with implied decimal. If you set to S or D, the program treats as =0. If a number’s integer value with implied decimal exceeds the maximum integer value (2,147,483,647), the program substitutes the maximum integer value for that number.

    Text files

    Set to the number of decimal places to format in text records. If you do not code , the program uses the default value of 2. If you specify DELIMITER, the program writes variable-length values and truncates trailing zeros, otherwise the program writes fixed field lengths, based on the values of FIELDS.

    DBF files

    Set as for CUBE Voyager files. However, the program uses the [1] value for all the matrix data fields unless "M" immediately precedes the colon in PATTERN (for example, PATTERN=IJM:V). If you set PATTERN such that M varies in a record’s matrix data values, the program uses [#] appropriately.

Note: Regardless of file format and value format, CUBE Voyager can never store matrix values smaller than \(10^{-300}\) or larger than \(10^{300}\) . CUBE Voyager will cap values outside this range. In addition, calculations that result in values outside the double-precision number range, will result in an overflow condition.
  • MATO - DELIMITER - |S| - For text files only (FORMAT=TXT). Character that separates data values. When you code this subkeyword, the program writes data values in variable length and separates values with this character. If you do not specify DELIMITER, the program writes fixed field lengths, based on the values of FIELDS. Usually, you delimit data with a comma or space. To use a comma or space, enclose with quotes, ‘ ‘.

  • MATO - FIELDS - |IV4| - Field width for data values when DELIMITER is not specified. The number of values specified with FIELDS must match the number of letters in PATTERN (the "base" portion precedes the colon, and the "repeating" portion follows the colon). The first FIELDS value always sets the length for I. After exhausting the list of FIELDS values, the program reverts to the FIELDS value that corresponds to the repeating portion of PATTERN. If the FIELDS value that corresponds to a base portion of PATTERN is set to 0, the program omits the corresponding data.

    Examples:

    PATTERN=IJ:V FIELDS=4,4,6
    		  

    I will always be in 1-4

    J will always be in 5-8

    V will be in 9-14,15-20,21-26 …

    PATTERN=I:JVM FIELDS=4,4,6,2
    		  

    I will always be in columns 1-4

    J will be in 5-8, 17-20, 29-32 …

    V will be in 9-14, 21-26, 33-38 …

    M will be in 15-16, 27-29, 39-40 …

    PATTERN=IJM:V FIELDS=4,4,0,8
    		  

    I will always be in columns 1-4

    J will always be in 5-8

    M will not be written to the data records

    V will be in 9-16,17-24,25-32 …

  • MATO - FORMAT - |S| - Type of file written:

    TPP — Standard CUBE Voyager/TP+ matrices

    MINUTP — Standard MINUTP matrices

    TRANPLAN — Standard Tranplan matrices

    TRIPS — Standard TRIPS matrices (also used for CUBE Analyst)

    TXT — Text records of matrix values

    DBF — DBF records for matrix values

    Default value is TPP, unless you set PATTERN. With PATTERN set, the default value is TXT.

  • MATO - MAXFIELDS - |I| - Maximum number of value sets written on a single record. If not set, the program does not limit the size of a data record (there is a limit of 255 fields in a DBF record). A “value set” is the group of values that follow the colon in PATTERN.

    For example, with IJ:V,MAXFIELDS=10, the program writes at most 10 V values on a record. With IJ:VM,MAXFIELDS=10, the program would write at most 10 sets of VM values on a record, for a maximum of 20 fields.

    Use care with DBF files. If MAXFIELDS is less than the number of matrices specified with MO, the program will split a logical data record into multiple records. The results might be confusing.

    Bentley recommends that you always set MAXFIELDS.

    The program tests MAXFIELDS before writing a value set. If the repeating portion of PATTERN (the "repeating" portion follows the colon) is only V and the program encounters a string of zero values, the program will start a new record if starting a new record requires less space. The new record will begin with the next J containing a value. If the repeating portion of PATTERN is more than V (contains a J or M, or both), and V is zero, the program does not write the value set.

    Example

    FILEO MATO=TPPTEST.MAT, MO=1-5,
    NAME=HBWORK,HBOTHER,NHB,IXI,XX
    MATO[3]=DEMO12.DAT, FORMAT=MINUTP, MO=1,3,5-7,
    NAME[3]=PURP_5
    MATO[4]=TEST4.TXT, PATTERN=IJ:MV, MO=1-8,
    MAXFIELDS=1000, DELIMITER=','
    MATO[15]=TEST15.TXT, PATTERN=I:JMV, MO=3-7,42,
    FIELDS=4,4,2,6,
    =6*0, [3]=2
  • MATO - MO - |IVP| - List of working matrices that the program writes in the output file. You may index MO. Note that missing MO index values are acceptable when writing binary files but not when writing text files. The highest implicit or explicit index determines the number of matrices included in the output file. You may write the same working matrix more than one time.

    For example, with MO=1-5,11-15,MO[20]=1,MO[6]=31 the program will write 20. Nine of the matrices (11-19) will be empty because no data was entered for them. The program numbers output matrices monotonically beginning with 1.

  • MATO - NAME - |SV| - For TP+, CUBE Voyager, Tranplan, and TRIPS output files, specifies the names for the matrices. Each output matrix (specified by MO) does not require a name, but including a name helps document the file. Valid matrix names contain only alphanumeric characters, spaces, and underscores (_). CUBE Voyager programs reading the file can reference the matrices by name and/or number.

    For MINUTP and text output files, the program ignores NAME.

    For DBF output files, specifies user names for the record variables. NAME[1..n] will refer to the beginning n record fields, which will align with PATTERN. If there are three characters prior to the colon in PATTERN, NAMES[1-3] refers to those fields. NAME[n+1] refers to the first actual data field that corresponds with the first character following the “:” in PATTERN.

  • MATO - PATTERN - |S| - Sequence of characters that indicates the order the program writes values to the output records. Valid values of PATTERN are listed and described under FILEI MATIPATTERN. The program begins a new record each time either of the first two characters of PATTERN change values (exception: IJ:V begins new record for each I change).

  • PRINTO - |KF| - Specifies the name of the file where the output from a PRINT statement is to be directed using PRINT PRINTO=#.

  • PRINTO - APPEND - |?| - See APPEND under PRINT.

  • RECO - |KF20| - File name for the RECO specified. Each RECO must have an index [x] appended to it. If there is no index, the index is assumed to be 1. The indices need not be monotonic or sequential. Data written to this file is defined with the FIELDS keyword below and directed to the appropriate file using the RECO keyword on the write statement. See WRITE. Currently, DBF and MDB are the only file formats supported for this record file.

    Note: Bentley recommends producing database files no larger than 2 GB, the largest size that CUBE Voyager and CUBE Base can properly process.

  • RECO - CFORM - |I| - Length of field for all character variables that follow it on the statement, and do not have a specific format associated with it. A later occurrence of CFORM will reset the value for character variables following it. The allowed range is 1-255; the default is 15.

  • RECO - EXCLUDERECI - |S| - Used to exclude selected fields when using the RECI.ALLFIELDS include macro described under FIELDS above.

  • RECO - FIELDS - |S| - Defines the variable names to be written to the output RECO file. These variables are referenced as RO.name variables in the script. If a RECO variable name matches a variable in the RECI record, the RO.name variable will take on the same value as the matching RI.name variable each time a new RECI record is read. All RO. variables (with or without matching RI. variables) can be modified in the script, the current variable values are written to these fields in the RECO DBF file when the WRITE statement is executed. For RECO fields that have no matching RECI fields, the field values are NOT initialized when a new RECI record is read. For RECO fields that are not assigned a value in the script or do not have a matching RI. variable, they will be left empty in the output record. The include macro RECI.ALLFIELDS can be specified on the FIELDS list to indicate that all of the data fields on the input RECI file are to be included on this RECO output file. The RECI fields will be inserted on the RECO file at the location where this macro is found. Care should be taken to ensure that the other names in the FIELDS list do not conflict with the names on the RECI file.

    For backward compatibility to Voyager version 3.2, the RO. prefix of the RECO variable name can be omitted when referencing the variable in the script if the variable has no matching RECI variable and it is not referenced with the RO. prefix anywhere in the script (a 3.2 script would never have an RO. Prefix in the first place). However, it is strongly recommended that the RO. prefix be used at all times to avoid confusion.

  • RECO - FORM - |R| - Format specification (w.d) for all numeric variables that follow it on the statement, and that do not have a variable- specific format. A later occurrence of FORM will reset the value for numeric variables following it. The maximum value of w (the field width) is 20 and the maximum value for d (digits after the decimal) is 9—but d must be at least 2 less than w; the default is 10.2.

  • RECO - NAME - |S| - Optional. Used in conjunction with the FIELDS subkeyword.

  • RECO - REPORT - |?| - Can be specified to have the program print a listing of the fields (name, mode, length, decimals) as they will appear in the DBF. Default value is F.

  • RECO - Z - |S| - Optional. Used in conjunction with the FIELDS subkeyword. Required when writing MO or MD matrices.

Example: FILEO

RUN PGM=MATRIX
FILEI RECI = " LINK_DATA.DBF",SORT = -VULNERABIL
FILEO RECO[1] = "PRESCEENED_LINKS.DBF", FIELDS=A,B,rank_bas
NUMLINKS=RECI.NUMRECORDS ; number of records (links) in the input file
LOG PREFIX=CNT VAR=NUMLINKS ; writes the number of links to CNT.NUMLINKS
; in the *.var file
; PrescreenType and PRESCREEN value set in SM with KEYS
IF ({PrescreenType}=1) ; screen based on a fixed number of links
; (i.e., top N based on Vulnerability)
PRESCREEN={PRESCREEN}
ELSE ; screen based on a percentage of number of links
; in the input network (i.e., top N% of links based
; on Vulnerability)
PRESCREEN=ROUND(NUMLINKS*{PRESCREEN}/100)
ENDIF
LOG PREFIX=CNT VAR=PRESCREEN
RO.RANK_BAS=RO.rank_bas+1
Anode=RI.A
Bnode=RI.B
If (RO.rank_bas<=PRESCREEN)
If (Anode <={Zones} | Bnode <= {Zones}) ; prevents any centroid links
; from being included in set
; of links to be analyzed
RO.rank_bas=RO.rank_bas-1
Else
WRITE RECO=1
EndIf
EndIf
ENDRUN

FILET

Programs: Distribution, Fratar, Matrix

Sets temporary file paths. Keywords include:

FILET is used to specify where various temporary files are to be written.

FILET Keyword

  • PATH - |KS| - Specifies the path(s) to the disk area where any temporary files are to be written. When transposing is required, the transposed matrices are written to a temporary file and then recalled during stack processing. Up to two files are required for this process. The first file is the actual transposed data, and the second file is an index to the data file. The index file may not be necessary, and if it is, it will be relatively small. It may speed retrieval somewhat if the two files are on different physical drives. If there is a ram disk installed, then the index file might fit on it. The index file size will be zones * chunks * transposes * 4 bytes. Chunks depends upon the amount of RAM that is available for the transposing processing; it could be none.

    Assume a 1000 zone system, 20 matrices to be transposed, and 2 Mb of RAM available. The actual RAM requirement would be 1000 * 1000 * 20 * 4, or 80 Mb. The number of chunks would be 40 (80 Mb / 2 Mb). The index file would require 800,000 bytes of RAM. The amount required for the data would be something less than 80 Mb, depending upon how well it compresses. In most cases, the compressed data would require about 30 Mb.

    The values for PATH are entered as standard operating system paths. If PATH[1] is specified, and PATH[2] is not, or vice-versa, the non-specified path is set equal to the specified one. If neither is specified, they both will default to the path in the environment variable named TMP, or TEMP. The logic for determining the appropriate path, and opening the files is:

    • If the PATH=’ ‘, use current directory.

    • If the PATH is specified, use the PATH.

    • If not specified, and TMP is specified in the Operating System environment, use the TMP.setting. (Same logic for TEMP.)

    • If the open fails, Fatal.

Example

PATH=' ' ; use current directory for both
PATH=..\,R: ; up a directory for data, drive R: for index
PATH=c:\ d ; root of c: for data, current directory on d: for index

FILLMW

Programs: Distribution, Fratar, Matrix

Fill work matrices. Keywords include:

This statement is used to speed up the process of filling matrices with values from other matrices. Because of its structure, matrices can be very easily moved from input matrices to work matrices or from work matrices to other work matrices. Multiple matrices can be easily filled on one specification. The beginning MW target is the keyword and the values are the matrices that are to be moved into the target matrices. After the first value, the following values may be unqualified (they do not have to have MI.#. prefixed to their names/numbers). This is also true for MW sources.

MI sources may have .T affixed to indicate that they shall be transposed (see Example below).

Everything that can be done on a FILLMW statement can be accomplished by COMP statements, but FILLMW sets up very fast moves in contrast to internal computational solutions performed by COMP statements.

FILLMW Keyword

  • MW - |s| - Specifies the matrices to be moved directly from their source to the destination work matrices named on the keyword.

Example 1

; The following five statements all do the same thing
FILLMW MW[1]=mi.1.1(3)
FILLMW MW[1]=mi.1.1,mi.1.2,mi.1.3
FILLMW MW[1]=mi.1.time,mi.1.distance,mi.1.cost
FILLMW MW[1]=mi.1.1,2,3
FILLMW MW[1]=mi.1.time,distance,cost

; The next two statements illustrate the simplicity of FILLMW vs. COMP
FILLMW MW[11]=mw[1],2,3,9,6
COMP MW[11]=mw[1], mw[12]=mw[2], mw[13]=mw[3], mw[14]=mw[9], mw[15]=mw[6]

; An example of multiple keywords
FILLMW MW[1]=mi.1.1,2,3, MW[4]=mi.2.2,3,4
FILLMW MW[101]=mi.1.1(5), MW[1](3)
  ;will fill MW[101-108] with MI.1.1-5,MW[1,2,3]

Example 2

;--- FILLMW using transposed inputs

RUN PGM=MATRIX
    MATI=TEST_FILLMW.MAT
    MATO=TEST_FILLMW_2.MAT MO=1-2, 11-12

    FILLMW MW[1]=MI.1.1(2) ; write the original matrices
    FILLMW MW[11]=MI.1.1.T, 2.T ; write transposed matrices 1 & 2
    FILLMW MW[21]=MI.2.1.T(5) ;write transposed matrices 1 - 5
ENDRUN

FREQUENCY

Program: Distribution, Fratar, Matrix

Stratifies one matrix’s values based upon the values of another. Keywords include:

Use FREQUENCY to obtain a frequency of occurrence of the values of a work matrix. A typical use is for a trip length distribution, where the number of trips in a matrix is stratified according to the times from a time or distance matrix. The final results are reported at the end of all zone processing.

  • BASEMW - |I| - Work matrix number ( MW[ ] ) whose values will be used for the stratification (the time matrix for a trip length distribution).

  • RANGE - |RP| - Set of two, or three, numbers that establishes the valid values for stratification. The numbers are separated by a dash. The first number (RANGE[1]) is the lowest value for which there is to be a stratification. The second number (RANGE[2]) is the highest value for stratification. The third, optional, number (RANGE[3]) is an increment for stratification. If there is no increment, the default will be 1. During accumulation, if the value from BASEMW is less than RANGE[1], or higher than RANGE[2], the value from VALUEMW is accumulated into an out-of-range bucket.

  • REPORT - |IP| - Iterations for which the report will be printed. If this keyword is not specified, or if any of the values exceed the last iteration, the report will be printed for the last iteration. REPORT is used primarily only when the Matrix program is invoked as a process that runs in a multiple iteration mode (Distribution program).

  • TITLE - |S| - Title for identifying the final report at the end of the application.

  • VALUEMW - |I| - Work matrix number ( MW[ ] ) whose values will be accumulated according to the values of BASEMW (the trip matrix for a trip length distribution).

Example

FREQUENCY BASEMW=1,VALUEMW=2,RANGE=1-100,
TITLE='Work Trips vs. Minutes'
FREQUENCY BASEMW=1,VALUEMW=2,RANGE=0-100-0.5, REPORT=99

GOTO

Program: Distribution, Fratar, Generation, Matrix

Use GOTO to jump to statement named :label.

When GOTO is processed, flow immediately branches to the statement named label. Label can be within IF and LOOP blocks; but care should be taken if this is to be done.

label is a character string that must have a matching LABEL statement. The leading colon ":" is removed from label when determining the qualified name of the statement to branch to.

Note: The placement of a :label inside a JLOOP is not allowed. This prevents using GOTO from jumping into a JLOOP. A GOTO may be used inside a JLOOP to jump to a :label that is outside the JLOOP but not to one that is inside the JLOOP.

Example

GOTO buildhwy
GOTO :buildhwy

A statement that begins with : is a label statement, that has meaning with only GOTO statements. A label statement can be within IF and LOOP blocks; care should be taken if this is done. The leading ":" is ignored.

Example

GOTO buildhwy
.
.
:buildhwy
IF (expression) GOTO :buildhwy ; It is permissible to go backwards.

IF … ELSEIF … ELSE … ENDIF

Program: Distribution, Fratar, Generation, Matrix

IF (expression) ELSEIF (expression) ELSE (expression) ENDIF

IF/ENDIF blocks are used to determine if certain operations are to be performed. IF blocks may be nested, but they may not overlap LOOP, JLOOP, or other IF blocks. If a variable in the expression is MI.n.name, ZI.n.name, or MW[], the same rules for indexing in a COMP statement are applied. MI.n.name or MW[] should realistically only be used within a JLOOP.

For more information on IF syntax, see Chapter 3, "General Syntax" in this manual.

Lengthy IF expression solutions could be time consuming; it is suggested that they be used judiciously. Although IF expressions can be quite powerful for zonal selection, sometimes INCLUDE and EXCLUDE filters may provide a much more efficient selection process (see the examples in this section). The following control statements may be appended to a single IF statement:

BREAK CONTINUE COMP EXIT GOTO PRINT

Example

IF (time_to_bcd < 20) simple statement ;single IF with process
IF (expression) EXIT
IF ( ( j=3-5,6-30,57 & k=(2*j-4) ) || ((J*k) = 14-20,56) )
.
ELSEIF (loop_cntr > 10)
.
ELSEIF (loop_cntr > 5 && diff.time < 32)
.
ELSE
.
ENDIF
; The above IF example is rather esoteric,
; and probably can not be aided by a filter.
; The J selection could have been filtered, but that might have caused
; conflicts with the use of J in other parts of the expression.
; The following illustrates a more efficient process for using IF for
; lengthy zonal selections within JLOOPs
; ***** Inefficient *****
JLOOP
IF (I=i_ranges... && J=j_ranges...) statement
ENDJLOOP
; ***** More efficient *****
IF (I=i_ranges...)
JLOOP INCLUDE=j_ranges...
statement
ENDJLOOP
ENDIF

JLOOP … ENDJLOOP

Programs: Distribution, Fratar, Generation, Matrix

Control a J loop for processing matrices. Keywords include:

JLOOP ENDJLOOP blocks are used primarily to control computations on matrices that a single COMP MW[]= can not properly control. A JLOOP block causes the program to loop between the JLOOP statement and its ENDJLOOP varying J from Jbeg to Jend by increments of Jinc. The logic for JLOOP and ENDJLOOP processing is:

at JLOOP:

  • If J is specified, establish values for J, Jend, and Jinc.

  • Else set J=1, Jend=Zones, Jinc=1.

  • If (J < 1 or J > Zones or Jend <1 or Jend > Zones) fatal termination.

  • If (INCLUDE, and J fails INCLUDE) go to ENDJLOOP.

  • If (EXCLUDE, and J meets EXCLUDE) go to ENDJLOOP.

  • Next statement.

at ENDJLOOP:

  • Add Jinc to J.

  • If (Jinc > 0 and J <= Jend) go to statement following JLOOP.

  • If (Jinc < 0 and J >= Jend) go to statement following JLOOP.

  • If (INCLUDE, and J fails INCLUDE) go to ENDJLOOP.

  • If (EXCLUDE, and J meets EXCLUDE) go to ENDLOOP.

All statements between the JLOOP and ENDJLOOP statements are processed with the current value of J. JLOOP blocks may not be nested, and may not overlap other JLOOP, LOOP or IF blocks. COMP MW[]= statements are processed only for the current value of J. Only the following statements are valid within a JLOOP block:

BREAK CALL COMP CONTINUE EXIT

GOTO IF ELSEIF ELSE ENDIF

PRINT REPORT SET

Note: The placement of a :label inside a JLOOP is not allowed. This prevents using GOTO from jumping into a JLOOP. A GOTO may be used inside a JLOOP to jump to a :label that is outside the JLOOP but not to one that is inside the JLOOP.

  • J - |I| - Sets Jbeg, Jend and Jinc.

  • EXCLUDE - |I| - Optional. List of origin zones that the program will not process. If you include this keyword, the program will not process statements for these zones, and instead skip to the next zone.

  • INCLUDE - |I| - Optional. List of origin zones that the program will process. If you include this keyword, the program will only process statements for these zones.

Jbeg - Expression to initialize J; the value may not be less than 1, nor greater than Zones.

Jend - Expression that establishes the Jend for the loop; the value may not be less than 1 nor greater than Zones. If there is no Jend, Jend is set to Jbeg, and Jinc is set to 1.

Jinc - Expression that establishes the Jinc for the loop. If Jinc is not specified, Jinc is set to 1 or -1, depending upon the direction from Jbeg to Jend.

If Jbeg is not specified, Jend and Jinc can not be, and the values 1,Zones,1 are used. If Jend is not specified, Jinc can not be, and the values Jbeg and 1 are used. If Jinc is not specified, it is set to 1 ( -1, if Jbeg > Jend). Because all these values can be expressions, they must be separated by commas; if an expression contains any commas, it must be enclosed within ().

Example

JLOOP J=I EXCLUDE=500-535 ;process only intra zonal values
.         ; but exclude externals
ENDJLOOP
ROWSUM1 = 0 ROWSUM3=0
JLOOP     ; get rowsums for matrices
ROWSUM1 = ROWSUM1 + MW[1]
ROWSUM3 = ROWSUM3 + MW[3]
ENDJLOOP

LOOP...ENDLOOP

Programs: Distribution, Fratar, Generation, Matrix

Control a general variable loop. Keywords include:

  • LVAR = Lbeg, Lend, Linc

LOOP ENDLOOP blocks are used to repeat of a series of statements. LOOP initializes a variable; ENDLOOP compares the contents of the variable to another value, and branches back to the statement following the LOOP statement if the comparison fails. LOOP blocks may be nested; they may not overlap IF blocks. The process differs considerably from JLOOP. The logic is as follows:

at LOOP:

  • Initialize LVAR to Lbeg.

  • Proceed to next statement.

at ENDLOOP:

  • If Lend not specified, jump to next statement.

  • Compute Lend.

  • If Linc not specified:

  • Set Linc to 1 or -1 (if Lbeg and Lend are constants, and Lbeg > Lend)

  • Else compute Linc**.

  • Add Linc to LVAR.

  • Compare LVAR to Lend.

  • If (Linc > 0 and LVAR > Lend) jump to statement after

    ENDLOOP

  • If (Linc > 0 and LVAR <= Lend) jump to statement after LOOP If (Linc < 0 and LVAR < Lend) jump to statement after

    ENDLOOP

  • If (Linc < 0 and LVAR >= Lend) jump to statement after LOOP

Because of the flexibility of this logic, unpredictable results and/or endless loops can occur if care is not taken. This would only happen if the Lend and/or Linc values are expressions that contain variables which could be altered during the loop. On the other hand, the flexibility provides for powerful control. The loop will be processed at least one time regardless of Lend and Linc values. Most uses will involve constants. Because LVAR values can be expressions, Lbeg, Lend, and Linc must be separated by commas (standard white space delimiting can not be interpreted properly).

LOOP & ENDLOOP Keywords and Expressions

  • LVAR - Name of the loop control variable. LVAR is not protected during the loop; computational, program, and other LOOP statements can alter its value. LVAR must be followed by Lbeg, and optionally, Lend and Linc.

Lbeg - Numeric expression to initialize LVAR.

Lend - Numeric expression that LVAR is to be compared with when the ENDLOOP statement is processed. If it is not specified, it is assumed no comparison is to be made (rather meaningless loop).

Linc - Numeric expression that is to be added to LVAR before the ENDLOOP comparison is made. If Linc is not specified, it will be set to 1 (-1 if Lbeg and Lend are both constants and Lbeg < Lend; a backwards loop).

Example

LOOP iter=1,10 ; perform 10 iterations .
ENDLOOP
LOOP xyz=abc*def,ghi+jkl,mno/pqr
LOOP abc=xyz,xyz+2,2 ; nested LOOP
ENDLOOP
ENDLOOP
LOOP jj=10,3,-2.5 ; 10, 7.5, 5.0
ENDLOOP

PARAMETERS

Program: Matrix

Sets general parameters. Keywords include:

PARAMETERS Keywords

  • MAT VALCACHE - |KI| - Number of matrix rows to cache when dealing with the MATVAL function. Default value is 50. Each matval call requires a direct access lookup on the designated MATI. Each read of a row for matval results in a matrix row being read and stored for possible later use. In general, the larger the number, the more efficient matval is. Each value requires (zones*8 + 4) bytes of RAM. If too large a value is used, the RAM for cache might come from disk, which could possibly hinder performance. The user might have to experiment to determine the best number of his application.

  • MAXMW - |KI| - Optional. Maximum index for work matrices (MWs). Valid values range from 1 to 999. Default value is 999. Normally, you do not specify this keyword and override default value.

  • MAXSTRING - |KI| - Establishes the maximum length for a string variable’s value. The default is 100, but if it is desired to compute longer strings, the value must be defined. All string variables will have this possible length.

    The maximum is 32,000 characters.

  • TRAM - |KI| - Establishes the maximum amount of memory that is to be used for temporary storage when transposing matrices. The program will request the amount that it thinks will provide the most efficient processing. The amount of memory required to do the transposing in one pass is (Zones * (Zones+1) * 8 * NumberTransposes) bytes. However, allocating huge amount of memory (greater than 1 GB) sometimes actually slow down the process, so the default for TRAM is the smaller of 500 MB, the one pass memory requirement, and 80% of available physical memory divided by the number of processes (if running DISTRIBUTEINTRASTEP). It is specified in MB (1,000,000 bytes) and the valid range is between 4 and 2000 (4 MB to 2 GB). The specified amount is still subject to the 80% of available physical memory restriction. This is to prevent the program from using virtual memory (temporary work space on disk). The use of virtual memory will significantly affact the efficiency for the transposing process. Generally there is no reason to specify memory higher than the default but there are times when it is necessary to lower the TRAM setting so that there will memory available memory for other running processes. The TRAM setting is per process, so if DISTRIBUTEINTRASTEP is being used, the main process and each Cluster node will get the same setting. Please note that using DISTRIBUTEINTRASTEP in a MATRIX program with a large number of transpose processes may slow down the process because each process will have to create its own temporary transposed matrix file, increasing the demand for memory and disk access many folds.

  • ZONEMSG - |KI| - Optional. Frequency with which the program writes zonal timing messages to the run monitor or console.

    Value corresponds to number of zones. For example, with a value of 1, the program writes a message for every zone. With a value of 10, the program writes a message for every 10 zones. With a value of 0, the program writes no zonal messages. Specify a larger value to reduce run times.

    Program writes to the run monitor when initiated through Application Editor or voyager.exe. The program writes to the console when initiated through runtpp.exe.

    Valid values are greater than or equal to zero. Default value is 1.

  • ZONES - |KI| - Establishes the number of zones to process. If ZONES is not specified, and the program has no other way to identify the appropriate number of zones, it will be set to 100. If there are any input MATI statements processed, the default value for ZONES will be determined by the highest value from any MATI.

Example

ZONES=3000

PRINT

Programs: Distribution, Fratar, Generation, Matrix

Format and print a line of information. See PRINT for details about the standard CUBE Voyager statement.

Example

PRINT FORM=0 LIST=I,J,TOTAL(6.2CS) 'ABCDE'(6.3), FORM=LRCD,
LIST=N,JLOOP_J ;Note this line is a continuation
LIST= I(6) J(6) TOTAL1, TOTAL2, TOTAL3 FILE=PRINTFIL.001
PRINT FORM=6.0CDLR LIST=I,J,TOTAL1,TOTAL2 FILE=PRINTFIL.002

PRINTROW

Program: Distribution, Fratar, Matrix

Prints row of matrices. See PRINTROW for details about the standard CUBE Voyager statement.

Example

Examples of output with various parameters follow:

pagewidth=80
mw[1]=j
mw[2]=j include=1-5,31-60,90-100 exclude=35,83
printrow mw=1-2,1 form=LRD title='form=LRD'
printrow mw=1-21 form=6D base1=y maxperline=10,
title='form=6D base1=y, maxperline=10'

Resulting Output:

J: I=1 PRINTROW MW[1] form=LRD Tot=5,050
1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27: 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
50: 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
73: 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
96: 96 97 98 99 100
J: I=1 PRINTROW MW[2] form=LRD Tot=2,390
1: 1 2 3 4 5 - - - - - -- - - - - - - - - - -- - - - - - - - - - 31 32
33: 33 34 - 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
57: 57 58 59 60 -- - - - - - - - - - -- - - - - - - - - - -- - - - - - -
90: 90 91 92 93 94 95 96 97 98 99 100
J: I=1 PRINTROW MW[1] form=6D base1= Tot=5,050
1: 1 2 3 4 5 6 7 8 9 10
11: 11 12 13 14 15 16 17 18 19 20
21: 21 22 23 24 25 26 27 28 29 30
31: 31 32 33 34 35 36 37 38 39 40
41: 41 42 43 44 45 46 47 48 49 50
51: 51 52 53 54 55 56 57 58 59 60
61: 61 62 63 64 65 66 67 68 69 70
71: 71 72 73 74 75 76 77 78 79 80
81: 81 82 83 84 85 86 87 88 89 90
91: 91 92 93 94 95 96 97 98 99 100
J: I=1 PRINTROW MW[2] form=6D base1= Tot=2,390
1: 1 2 3 4 5 -- -- -- -- --
31: 31 32 33 34 -- 36 37 38 39 40
41: 41 42 43 44 45 46 47 48 49 50
51: 51 52 53 54 55 56 57 58 59 60
81: -- -- -- -- -- -- -- -- -- 90
91: 91 92 93 94 95 96 97 98 99 100

RENUMBER

Programs: Fratar, Matrix

Renumbers (aggregate, split) zones for output matrices. Keywords include:

RENUMBER causes the program to assign new zone numbers to all values in the output matrices. This causes an extra layer of processing, because the matrices must be saved, and then retrieved and combined after all normal processing is completed. Each input zone must be assigned a new output zone number, and a pair of percentages (ROWPCT and COLPCT) to indicate how the outgoing matrix zonal values are to be allocated to the renumbered zones. These equivalencies are obtained from records in the designated FILE. The records may have from one to four fields to specify the renumbering. A semi-colon (;) terminates data on a record; anything following the ; is a comment.

The standard fields are:

IPZONE - Input zone number

OPZONE - Output zone number

ROWPCT - Percentage of IPZONE’s values to be assigned to OPZONE when renumbering the IPZONE row

COLPCT - Percentage of IPZONE’s values to be assigned to OPZONE when renumbering the IPZONE columns

If there is only one field, OPZONE is set to 0.

If there are less than three fields, ROWPCT and COLPCT are set to 100.

If there are three fields, COLPCT is set to ROWPCT. ROWPCT and COLPCT may not exceed 327

An alternate record format for aggregating several zones into a single district:

District - Word that begins with the letter D (for traditional DISTRICT). The word may be any length, but the first character must be D.

OPZONE - Output zone number; it MUST be followed by "=".

IPZONEs - Remaining fields are the input zones that are allocated 100% (ROWPCT and COLPCT) into OPZONE. Two fields may be separated by a dash ("-") if the two are to form a range.

If the list of IPZONEs is large, and the length of the record would exceed 250 characters, the record must be broken into several records. Each record must begin with the District string, and may not terminate with a dash.

Example

D 1=1-10,20-30 45,48, 58-60
D 1=100-110 200-210 300-305 410 415 500-515

Those two formats can be mixed in the same file to allow efficient specification of zonal equivalencies.

An IPZONE may appear more than one time; usually the case when a zone is to be split into several new zones. An OPZONE may appear more than one time, usually the case when aggregating zones. The sum of all ROWPCTs and COLPCTs for each IPZONE should each be 100; if not, a message is issued. Every IPZONE (1-IPzones) should be fully allocated. An IPZONE of 0 means there is intentionally no IPZONE for the OPZONE. An OPZONE of 0 means there is intentionally no OPZONE for the IPZONE. There should be an OPZONE for every zone (1-OPZONES); if not, a message is issued.

To accommodate this process, the normal output matrices are trapped, renumbered, and saved, at the normal output phase. When all zones have been processed, the saved matrices are retrieved in appropriate order, combined when necessary, and written to the MATO files. The intermediate matrices are saved either in RAM (normal format), or on disk files (compressed format). If saved on disk, there must be sufficient disk space for both the intermediate rows, and the final output files. The process is optimized to the extent possible; the use of the FILES and INRAM keywords could help considerably in reducing running times.

RENUMBER Keywords

  • FILE |F| - File that contains the zonal equivalencies. FILE and ZONEO are mutually exclusive. Only one of those two keywords can be used at one time.

  • FILES |I| - Number of temporary files to use to store intermediate factored matrix rows, until they can be sorted and combined in the final stages of the application. The value must be in the range 1-10, inclusive. If the keyword is not specified, the program will set the value to ZONES/100, but never less than 1, nor greater than 10. The number of files affects the running time when the final matrices are being formed; more files generally speeds up the final stage. Ten files will normally reduce the application time by a factor of about 20-35 per cent as compared to one file.

  • MISSINGZI |S| - Single character (if a longer string is specified, only the first character is processed) to indicate how to treat input zones that are not fully allocated (ROWPCT and COLPCT totals of 100). The character may be F, W, or M, and if it is none of these, or MISSINGZI is not specified, it defaults to F. The meanings are:

    F — Fatal

    W — Warning

    M — Message only (no penalty associated)

  • MISSINGZO |S| - Indicator similar to MISSINGZI. It indicates the level of error associated with gaps in the OPZONE structure.

  • ZONEO |S| - Alternate method of specifying zonal equivalencies using an input zonal data file. A typical value of ZONEO is an input zonal attribute: ZI.**.***. In this convention, the IPZONE is the current zone number and the OPZONE is the specified input zonal attribute, for example, district or TAZ number. ZONEO and FILE are mutually exclusive. Only one of those two keywords can be used at one time.

  • ZONES |I| - Designates the highest new zone number and serves as an editor as the file records are read, to ensure that each OPZONE doesn’t exceed this value. If ZONES is not designated, no edit is performed, and ZONES is set to the highest OPZONE. A check is made to ensure that there is an OPZONE for all values: 1-ZONES; if there are any gaps, a message is issued.

Example 1

FILEI MATI=IN.MAT
FILEO MATO=OUT.MAT, MO=1
MW[1]=MI.1.1 ; must load values into MW[1], else OUT.MAT will be all zeros
; renumber OUT.MAT according to 2005ZON.EQ
RENUMBER FILE=2005ZON.EQ, MISSINGZI=M, MISSINGZO=W

Example 2

FILEI MATI=IN.MAT,
ZDATI=ZDATIN.DAT, Z=#1, DIST=2
FILEO MATO=OUT.MAT, MO=1
MW[1]=MI.1.1 ; must load values into MW[1], else OUT.MAT will be all zeros
; renumber OUT.MAT according to ZDATIN.DAT
RENUMBER ZONEO=ZI.1.DIST

Example 3

/* This is a two step process to show an example of using RENUMBER to split an existing pair of trip tables for a new disaggregate zone system. A typical process might be to split zones into fully nested sub zones in ArcView. This example assumes such a spatial procedure has been preformed and the resulting dbf file has the zonal area of both the parent zones and the new split zones. This first step uses MATRIX to compute split factors based on the ratio of the new zone-to-old zone area and writes out the zonal equivalency file for use in the subsequent renumbering step.
*/
;STEP 1
RUN PGM=MATRIX
FILEI ZDATI[1] = TAZDATA1.DBF
; Data structure of TAZDATA1.DBF is:
;Z NEW_Z1 NEW_Z2 Z_AREA Z1_AREA Z2_AREA
;1 1 2 6.40 2.22 4.18
;2 3 4 6.42 3.18 3.24
;3 5 6 6.44 3.78 2.66
;4 7 8 6.46 2.58 3.88
;5 9 10 6.48 3.75 2.73
;. . .
PARAMETERS ZONES=2999
; establishes a split factor based on the new zone geography
; the split factor is the ratio of the area of the new zone to the area
; of its parent. This set up assumes all input zones are split into two output zones
; and that the total area of the new zones is equal to the area of the parent zone.
SPLIT1=100*(ZI.1.Z1_AREA/ZI.1.Z_AREA)
SPLIT2=100-SPLIT1
; writes the split factors to the PRN file
PRINT LIST=SPLIT1,SPLIT2
; write the zonal equivalency file
PRINT LIST=I,ZI.1.NEW_Z1,SPLIT1,
    FILE = EQUIV_1.DAT"
PRINT LIST=I,ZI.1.NEW_Z2,SPLIT2,
    FILE = EQUIV_1.DAT"
; data structure of EQUIV_1.DAT is :
;   1.00    1.00     34.69
;   1.00    2.00     65.31
;   2.00    3.00     49.53
;   2.00    4.00     50.47
;   3.00    5.00     58.70
;   3.00    6.00     41.30
;   4.00    7.00     39.94
;   4.00    8.00     60.06
;   5.00    9.00     57.87
;   5.00    10.00    42.13
;. . .
ENDRUN
;STEP 2 – split input trip table to new zonal system
RUN PGM=MATRIX
FILEO MATO[1] = TRIPS2.MAT,
MO=1-2, NAME=AUTO, TRANSIT
FILEI MATI[1] = TRIPS1.MAT
mw[1]=mi.1.1 ; fill work matrix 1 with AUTO trips from input matrix 1
mw[2]=mi.1.2 ; fill work matrix 2 with TRANSIT trips from input matrix 2
RENUMBER,
    FILE = EQUIV_1.DAT
; the zonal equivalency file has the fields IPZONE, OPZONE and ROWPCT
; the default when no COLPCT is specified is to set the COLPCT=ROWPCT.
; if different COLPCT factors are desired they would need to be specified in the
; fourth column of the file.
ENDRUN

REPORT

Program: Matrix

Request reports and establish tracing. Keywords and sub-keywords include:

REPORT keywords

  • MARGINREC - |K?| - Switch that indicates that MARGIN summary records for each zone are to be written to the standard output and/or a designated file. It differs from the function of the MARGINS keyword. The keywords that are subordinate to MARGINREC are a subset of those available on a standard CUBE Voyager PRINT control statement as shown below. Variable values are formatted to the zonal record; normally, the variables are row and column values obtained from the accumulation of margin values for work matrices, but any variable or literal string can be specified.

  • MARGINREC - CFORM - |S| - Format to use for any character data items that appear after this keyword.

  • MARGINREC - FILE - |F| - Specifies a file where the formatted list is to be written. Only one FILE value is allowed per each MARGINREC switch. A separate file is written for each MARGINREC FILE value. If names conflict, the earlier files will be overwritten.

  • MARGINREC - FORM - |S| - Format to use for any numeric data items that appear after this keyword.

  • MARGINREC - LIST - |KSV| - Specifies the items (variables and/or strings) that are to be formatted to the print line. If it is desired to have an explicit format for any item in the list, there may be a format appended to the it. Such a format is surrounded by (); the format applies to only that item.

    Example:

    J ITEM1(6) ITEM2(8C)'abcde' 'i='(8R) K(L)

    The variables are normally a character (R, C, or I) followed by a number. R1 indicates the row total for work matrix one; C2 indicates the column total for work matrix two, and I4 is the intrazonal value for work matrix four. Variables can be formed by concatenating R, C, and I names with an underscore ‘_’ acting as the concatenating character. Example: R1_C1 is the sum of the row value and the column value for the zone. I1_I2_I3 is the sum of the intrazonal values for matrices one, two, and three.

    Other variables can be inserted into the record, but the most meaningful one would be J. A record is written for each zone (J=1,Zones), and J is the zone variable that is used.

  • MARGINREC - PRINT - |?| - Switch that indicates that the FILE record is to also be written to the standard printed output.

  • MARGINS - |KIP| - Requests that row and column totals be accumulated and reported for the specified MWs (work matrices). If, for some reason, there is insufficient RAM to accumulate all the totals, the program will delete (and notify) some, or all, of the requests as required. Each MW report is listed in telephone book style with empty zones being omitted.

    Note: MARGINS and MARGINREC cause the program to accumulate margin values for each zone for each of the included matrices. If there is insufficient RAM, margin accumulation could be canceled for certain matrices.

  • MATSTAT - |S3| - Specifies desired matrices for which statistical summaries will be formatted and reported in the run print file. Valid values are: MI, MO, and MW to generate reports for input matrices, output matrices and working matrices.

  • TRACE - |K?| - Controls the listing of the stack statements as they are processed (can be quite voluminous, so be careful). Trace can be turned on and off at any time, thus controlling the amount of output as desired. If a COMP is traced, only the first five J values will be reported.

  • ZDAT - |?| - Switch that indicates that the zonal data arrays generated by any FILEI ZDATI keywords are to be formatted and reported.

  • ZDAT - DEC - |I| - Sets the maximum number of decimal places to be printed for any variable. This one value applies to all variables on all ZDATI statements.

Example

These statements illustrate REPORT.

REPORT MARGINS=1-3,8 ; request margins summaries REPORT TRACE=y ; turn stack tracing on
REPORT TRACE=n ; turn stack tracing off
MARGINREC=y LIST=J,R1,C1,R2,C2,R3_R4_C3_C4,R5_C5
MARGINREC=y LIST=J,' sum intras for 1-3=', I1_I2_I3,
FILE=r:\intras,print=y
REPORT MATSTAT=MW ; request statistical summaries for working matrices

Example MATSTAT REPORT:

Table 1 - Matrix Summary (625 cells)
----------- Sum ----------- ---- Cnt --- ----------- Ave ----------
ALL >0 <0 >0 <0 ALL >0 <0
MW[1] 16,455.14 16,455.14 -- 256 -- 26.32822 64.27789 --
MW[2] 9,923.04 9,923.04 -- 256 -- 15.87686 38.76187 --
MW[3] 978.99 978.99 -- 256 -- 1.56638 3.82418 --
MW[4] 27,357.17 27,357.17 -- 256 -- 43.77147 106.86395
Table 2 - Matrix Min/Max (625 cells)
---------- Minimum -------------- ------------ Maximum --------------
>0 @I-J <0 @I-J >0 @I-J <0 @I-J
MW[1] 2.5450 3-16 -- --- 1,007.71 13-13 -- ---
MW[2] 3.1050 3-16 -- --- 370.64 13-13 -- ---
MW[3] 0.1015 13-12 -- --- 39.65 1-1 -- ---
MW[4] 6.0145 3-16 -- --- 1,378.97 13-13 -- ---
Table 3 - Matrix Intrazonal Summary (625 cells)
---------- Sum ---------- ---- Cnt --- ----------- Ave --------------
ALL >0 <0 >0 <0 ALL >0 <0
MW[1] 3,059.99 3,059.99 -- 16 -- 4.895984 191.24937 --
MW[2] 1,629.70 1,629.70 -- 16 -- 2.607520 101.85625 --
MW[3] 178.27 178.27 -- 16 -- 0.285232 11.14187 --
MW[4] 4,867.96 4,867.96 -- 16 -- 7.788736 304.24750 --
Table 4 - Matrix Intrazonal Min/Max (625 cells)
---------- Minimum ------------- ------------ Maximum --------------
>0 @I-J <0 @I-J >0 @I-J <0 @I-J
MW[1] 4.82 3-3 -- --- 1,007.71 13-13 -- ---
MW[2] 6.09 12-12 -- --- 370.64 13-13 -- ---
MW[3] 0.12 5-5 -- --- 39.65 1-1 -- ---
MW[4] 18.74 7-7 -- --- 1,378.97 13-13 -- ---

SET

Programs: Distribution, Fratar, Generation, Matrix

Stores numeric values into one, or more, variables. Keywords include:

Use SET to set any number of variables to some value. All variables are set to zero at the beginning of the I-loop, and are then changed only by the user. Most changes are the result of COMP statements. A COMP statement can accomplish all that SET does, but it is not as efficient, and is somewhat wordier.

SET Keywords

  • VAL - |R| - Numeric value that the VARS that follow will be set to. VAL is initialized to zero when the statement is started, and then reset as this keyword is encountered. If there is no VAL, the coded VARS are all set to zero.

  • VARS - |S| - List of variables that are to be set to the more recent value of VAL obtained from this statement. If a named VARS is an array allocated by an ARRAY statement, the entire array is set to the value of VAL.

Example

SET VAL=0, VARS=TOT1,TOT2,COUNTER
COMP TOT1=0 TOT2=0 COUNTER=0 ; is the same as previous statement
SET VARS=TOT1 TOT2 COUNTER ; is also the same (VAL defaults to 0)
SET VAL=123 VARS=C123, VARS=TOT1, TOT2, TOT3 ; sets all to 123
ARRAY SUMS=50
SET VAL=100, VARS=SUMS ; sets all 50 cells of SUMS to 100
SET VARS=SUMS ; sets all 50 cells of SUMS to 0

SORT

Programs: Distribution, Fratar, Generation, Matrix

Sort user-defined arrays. Keywords include:

  • ARRAY

  • NUMRECS

See SORT for details about the standard CUBE Voyager statement.

Example

ARRAY ZONENO=ZONES, HH=ZONES, INCOME=ZONES
.
.
ZONENO[I] = I
HH[I] = ZI.1.HH[I]
INCOME[I] = ZI.1.INCOME[I]
.
.
SORT ARRAY=-INCOME,-HH,ZONENO, NUMRECS=ZONES
LIST=’ Zone Income HHs’
JLOOP
PRINT FORM=8, LIST=ZONENO[J], INCOME[J], HH[J]
ENDJLOOP

WRITE

Programs: Distribution, Fratar, Generation, Matrix

Output record data files to DBF format. Keywords include:

Use WRITE to specify the record files that are to be written at the end of each I zone.

WRITE Keyword

  • RECO - |I| - Number of the FILEORECO[#] DBF file where you want to direct this print output.

XCHOICE

Program: Matrix

XCHOICE implements a logit choice model. XCHOICE replaces the CHOICE command statement, resulting in improved run times. Though you can continue to use CHOICE, Bentley recommends using the XCHOICE command statement for logit choice models. Usage is similar with XCHOICE, but there are some differences in keyword usage and in value formats for keywords. See Summary of syntax usage differences between XCHOICE and CHOICE.

Use the XCHOICE command to implement logit choice models, based on either generalized costs or utilities. The actual keywords supported depend on whether you use cost-based or utility-based models:

XCHOICE keywords: Cost-based models

Keywords and sub-keywords applicable to XCHOICE cost-based models include:

XCHOICE keywords: Cost-based models

  • ALTERNATIVES - |S99| - Lists the set of discrete choices in the forecast scenario. If the model is confined to destination choice, then the alternatives list comprises just one item (representing the demand matrix). The names used in the alternatives list are subsequently used in SPLIT or DESTSPLIT keywords which define the structure of the logit choice model, and also determine the order that input or output data are specified.

  • BASECOSTSMW - |S99| - Supplies the names of the base cost matrices. For lists of two or more matrices, the order must match the list of choices given in the ALTERNATIVES keyword.

    This keyword is only used in incremental models which specify base and forecast costs (as opposed to cost differences). The corresponding forecast costs are specified using the COSTSMW keyword.

  • BASEDEMANDMW - |S99| - Supplies the names of the base demand matrices. For incremental models only. For lists of two or more matrices, the order must match that in the ALTERNATIVES keyword.

  • COSTSMW - |S99| - Specifies forecast costs matrices. If there is more than one cost specified, their order must be the same as that used in the ALTERNATIVES keyword.

    See also BASECOSTSMW and DCOSTSMW (cost- differences) for incremental models; the COSTSMW keyword is not used in conjunction with DCOSTSMW.

  • DCOSTSMW - |S99| - Gives the change in cost for each choice rather than the base and forecast costs. For incremental models only. These cost-differences may be specified as matrices, or numeric values such as 0.0.

  • DEMAND - |S99| - The demand value for a destination-choice or mode- and destination-choice model.

  • DEMANDMW - |S99| - The demand matrix for a pure mode-choice model.

  • DESTSPLIT - |S99| - Use the DESTSPLIT keyword when the nest in the hierarchy corresponds to a destination-choice model. It divides the travel demand between destination zones, rather than alternatives. The output list must comprise just one item, representing either a distinct choice from the ALTERNATIVES keyword or an output which links to a subnest.

    Like the SPLIT command, it may be specified in one keyword or divided into constituent parts by use of the COEFF and SPLITINTO subkeywords. Examples are:

    DESTSPLIT = TOTAL, 0.3, allTrips, 
    		  

    and

    DESTSPLIT = TOTAL, COEFF = 0.3, SPLITINTO = allTrips,

    By default the destination choice model works over all zones. By using the INCLUDE or EXCLUDE subkeywords the choice process may be restricted to a subset of all zones. The following example shows destination choice over zones 1 to 57:

    DESTSPLIT=TOTAL,0.3,allTrips,INCLUDE=1-57,

    and this shows destination choice over zones except for 88 to 100, which are specified by the EXCLUDE subkeyword:

    DESTSPLIT = TOTAL, COEFF = 0.3, SPLITINTO = allTrips, EXCLUDE = 88-100, 
    		  

    Note: Certain restrictions apply to the use of destination-choice models. The composite costs may not be saved, and this form of logit model may not be used inside a JLOOP construct.

    • COEFF - |R| -

    • INCLUDE - |IPa| -

    • EXCLUDE - |IPa| -

    • SPLITINTO - |S99|

  • ODEMANDMW - |S99| - Specifies which working matrices (MWs) store the forecast demand; the list comprises a list of working matrix numbers. If there is more than one cost matrix, then the list must be in the same order as used in the ALTERNATIVES keyword.

  • SPLIT - |S99| - The structure of the logit choice model is specified by the SPLIT and DESTSPLIT keywords. One of these keywords is required for each nest (or subnest) in the model hierarchy. For a hierarchic model, these are typically specified starting at the top level and working down the structure.

    Each SPLIT keyword specifies an input, a scale parameter (or coefficient of cost), and one or more outputs. The coefficient and outputs may both be specified in the SPLIT keyword or specified using the COEFF and SPLITINTO subkeyword clauses.

    The input (or first item listed in a SPLIT keyword) may either be TOTAL (representing the total demand at the top level of the choice hierarchy) or for subnests it is the name of an output from the appropriate higher level nest.

    The coefficient is specified as the second item in the SPLIT keyword, or using the COEFF subkeyword. It may be specified as a numeric value, a variable, or even a matrix with differing values between origin-destination pairs. The latter is appropriate when the demand matrix comprises distinct segments (such as travel within study area, trips from cordon into study area, and through traffic) and these segments respond differently to cost differences.

    The remainder of the SPLIT keyword, or the SPLITINTO subkeyword define the output list. The items represent either distinct choices (from the ALTERNATIVES keyword), or links to sub-nests which are given unique meaningful names and used as inputs to lower splits.

    The following examples shows a subnest taking AllPT as an input and using a scale parameter of 0.3 to divide between bus and rail alternatives. Specified as a SPLIT keyword it takes the form:

    SPLIT = AllPT, 0.3, Bus, Rail, 
    		  

    and using subkeywords it is:

    SPLIT = AllPT, COEFF = 0.3, SPLITINTO = Bus, Rail, 
    		  

    The SPLITCOMP subkeyword specifies the working matrix to store the composite costs or composite utilities for the nest defined by its parent SPLIT keyword.

    Example:

    XCHOICE ALTERNATIVES = A,b,c,
    baseCOSTSmw = 2,3,4,
    COSTSmw = 2,3,5,
    basedemandmw=1,1,1,
    ODEMANDmw=6,7,8,
    SPLIT= Total 0.1 desta, destpt,
    SPLITCOMP=20,
    destSPLIT= desta 0.15 a,
    destSPLIT= destpt 0.15 pt,
    SPLIT= pt 0.2 B C,
    SPLITCOMP=21,
    startmw=30
    MW 20 is composite cost of alternative
    "Total"
    MW 21 is composite cost of alternative
    "pt"
    
    • COEFF - |R|

    • SPLITINTO - |S99|

    • SPLITCOMP - |S99|

  • STARTMW - |I| - The calculations performed by the logit choice model require a number of working matrices (or MWs) to be allocated for the use of the XCHOICE command. The STARTMW keyword specifies a numeric value corresponding to a particular working matrix which is higher than that of any other working matrix referenced in the script. Working matrices from the STARTMW value upwards are used by the XCHOICE command, and should not be used elsewhere in the script. Where a Matrix script contains several XCHOICE commands, the same STARTMW value may be used in all instances.

XCHOICE keywords: Utility-based models

Keywords and sub-keywords applicable to XCHOICE utility-based models include:

XCHOICE keywords: Utility-based models

  • ALTERNATIVES - |S99| - Lists the set of discrete choices in the forecast scenario. If the model is confined to destination choice, then the alternatives list comprises just one item (representing the demand matrix). The names used in the alternatives list are subsequently used in SPLIT or DESTSPLIT commands which define the structure of the logit choice model, and also determine the order that input or output data are specified.

  • BASEDEMANDMW - |S99| - Supplies the names of the base demand matrices. For incremental models only. For lists of two or more matrices, the order must match that in the ALTERNATIVES keyword.

  • BASEUTILSMW - |S99| - Supplies the names of the base utility matrices for the various alternatives. For lists of two or more matrices, the order must match that given in the ALTERNATIVES keyword.

    This keyword is only used in incremental models which specify base and forecast utilities (as opposed to utility differences). The corresponding forecast costs are specified using the UTILITIESMW keyword.

  • DEMAND - |S99| - The demand value for a destination-choice or mode- and destination-choice model.

  • DEMANDMW - |S99| - The demand matrix for a pure mode-choice model.

  • DESTSPLIT - |S99| - Use when the nest in the hierarchy corresponds to a destination-choice model. It divides the travel demand between destination zones, rather than alternatives. The output list must comprise just one item, representing either a distinct choice from the ALTERNATIVES keyword or an output which links to a subnest. This output item may be preceded by a scale parameter.

    The following example applies a scaling factor to the ModeSplit logsum utility, and performs a destination choice dividing the total trips across all destinations:

    DESTSPLIT = TOTAL 0.9 ModeSplit,

    By default the destination choice model works over all zones. By using the INCLUDE or EXCLUDE subkeywords the choice process may be restricted to a subset of all zones. The following example restricts destination choice to zones 1 to 23:

    SPLIT = TOTAL, allTrips, INCLUDE = 1-23, 
    		  

    Note: Certain restrictions apply to the use of destination choice models. The composite utilities cannot be saved, and this form of logit model may not be used inside a JLOOP.

    • INCLUDE - |IPa|

    • EXCLUDE - |IPa|

  • DUTILSMW - |S99| - Gives the change in utility for each choice rather than the base and forecast utilities. For incremental models only. These utility-differences may be specified as matrices, or numeric values such as 0.0.

  • ODEMANDMW - |S99| - Specifies working matrices (MWs) used to store the forecast demand; the list comprises a list of working matrix numbers. If there is more than one cost matrix, then the list must be in the same order as used in the ALTERNATIVES keyword.

    This command is optional, and may be omitted if only the composite costs are required.

  • SPLIT - |S99| - The structure of the logit choice model is specified by the SPLIT and DESTSPLIT keywords. One of these keywords is required for each nest (or subnest) in the model hierarchy. For a hierarchic model, these are typically specified starting at the top level and working down the structure.

    Each SPLIT keyword specifies an input, and one or more outputs which may have their own scale parameters. (A choice with only one output may be specified to apply a scaling factor to a subnest logsum utility, and so achieve consistent scaling at all equivalent levels in a complex hierarchic structure.)

    The input (or first item listed in a SPLIT keyword) may either be TOTAL (representing the total demand at the top level of the choice hierarchy) or for subnests it is the name of an output from the appropriate higher level nest.

    The remainder of the SPLIT keyword define the output list, and any scale parameters which apply to subnests.

    The main items in the output list represent either distinct choices (from the ALTERNATIVES keyword), or links to subnests which are given unique meaningful names and used as inputs to lower splits. An example is:

    SPLIT = AllPT Bus Rail, 
    		  

    Subnests in the output list may be preceded by a scale parameter, which is applied to the composite (or logsum) utility of the subnest before evaluating this choice nest. The scale parameter should be greater than 0, and must not exceed 1.0.

    For utility-based models, if one alternative has a scalar, all others must also have scalars. For example:
    split=total,0.5,auto,1.0,pt, 
    		  

    Scalars of 1.0 cannot be omitted in XCHOICE.

    Examples are:

    SPLIT = TOTAL 1.0 Car 0.5 PT 0.4 WalkCycle,

    where scale parameters are applied to the PT and walk/cycle subnests. Car either is a distinct alternative, or a subnest with a scale parameter of 1.0.

    Where the same scale parameter applies to several sub- nests, the scale parameter may be specified once followed by the list of relevant subnests grouped together by use of brackets. An example is:

    SPLIT = TOTAL, 0.4 Car 0.5 (BusRail),

    where the bus and rail subnests share the same scale parameter, and a different value applies to the car subnest.

  • STARTMW - |I| - The calculations performed by the logit choice model require a number of working matrices (or MWs) to be allocated for the use of the XCHOICE command. The STARTMW keyword specifies a numeric value corresponding to a particular working matrix which is higher than that of any other working matrix referenced in the script. Working matrices from the STARTMW value upwards are used by the XCHOICE command, and should not be used elsewhere in the script. Where a Matrix script contains several XCHOICE commands, the same STARTMW value may be used in all instances.

  • UTILITIESMW - |S99| - Specifies forecast utilities. If there is more than one utility, their order must be the same as that used in the ALTERNATIVES keyword.

    See also BASEUTILSMW and DUTILSMW (utility- differences) for incremental models; the UTILITIESMW keyword is not used in conjunction with DUTILSMW.

Summary of syntax usage differences between XCHOICE and CHOICE

In each XCHOICE, there must be one and only one case-insensitive "Total" in a SPLIT clause. "Total" is the starting node for mode split.

All matrix valued keywords must end with MW. For example: UTILITIES is now UTILITIESMW. COSTS is now COSTSMW.

DEMANDMW is only available to pure mode choice models where input demand is a matrix. In destination-choice or mixed mode- and destination-choice models, use DEMAND instead. DEMAND in XCHOICE can be any of these values: Constant, Variable, Array without index, Array with constant index, Array with variable index.

For example:

....
array tripsfromi=5
if(i==1)
tripsfromi[1]=100
tripsfromi[2]=200
tripsfromi[3]=300
tripsfromi[4]=400
tripsfromi[5]=500
endif
myvar=100
myindex=3 ...
DEMAND =100,
.OR.
DEMAND =myvar,
.OR.
DEMAND =tripsfromi,
.OR.
DEMAND =tripsfromi[1],
.OR.
DEMAND =tripsfromi[myindex],

For mixed mode- and destination-choice models, DESTSPLIT must start with alternatives prefixed with "dest" (for example, destx), and end with corresponding alternative name, for example "x." Here is an example:

ALTERNATIVES=car b c,
SPLIT = TOTAL 0.01 destcar destpt,
DESTSPLIT = destcar 0.02 car,
DESTSPLIT = destpt 0.03 pt,

Both "x" or "destx" are acceptable in the higher level SPLIT clause. In previous example, both of these two following cases work:

SPLIT = TOTAL 0.01 destcar destpt, 
	 

Or

SPLIT=TOTAL 0.01 car pt, 
	 

For utility-based model, if one alternative has a scalar, all others must also have scalars, example:

split=total,0.5,auto,1.0,pt, 
	 

Scalar 1.0 can be omitted in CHOICE, but it cannot be omitted in XCHOICE.

OCOMPCOST and OCOMPUTIL in CHOICE are replaced by a new keyword SPLITCOMP in XCHOICE. Unlike OCOMPCOST and OCOMPUTIL, which can be used only on the upper most level of a nested mode choice structure, SPLITCOMP can be used on any level to get nest specific composite costs or composite utilities.